diff --git a/src/app/+item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html b/src/app/+item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html index 35561ff995..dc017a9f92 100644 --- a/src/app/+item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html +++ b/src/app/+item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html @@ -25,17 +25,18 @@
-
+
{{'item.edit.bitstreams.headers.name' | translate}}
-
{{'item.edit.bitstreams.headers.description' | translate}}
-
{{'item.edit.bitstreams.headers.format' | translate}}
-
{{'item.edit.bitstreams.headers.actions' | translate}}
+
{{'item.edit.bitstreams.headers.description' | translate}}
+
{{'item.edit.bitstreams.headers.format' | translate}}
+
{{'item.edit.bitstreams.headers.actions' | translate}}
+ [item]="item" + [columnSizes]="columnSizes">
-
+
{{'item.edit.bitstreams.bundle.name' | translate:{ name: bundle.name } }}
-
+
- + diff --git a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts index 6da37b436b..a3a02bce9b 100644 --- a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts @@ -4,12 +4,21 @@ import { TranslateModule } from '@ngx-translate/core'; import { NO_ERRORS_SCHEMA, ViewContainerRef } from '@angular/core'; import { Item } from '../../../../core/shared/item.model'; import { Bundle } from '../../../../core/shared/bundle.model'; +import { ResponsiveTableSizes } from '../../../../shared/responsive-table-sizes/responsive-table-sizes'; +import { ResponsiveColumnSizes } from '../../../../shared/responsive-table-sizes/responsive-column-sizes'; describe('ItemEditBitstreamBundleComponent', () => { let comp: ItemEditBitstreamBundleComponent; let fixture: ComponentFixture; let viewContainerRef: ViewContainerRef; + const columnSizes = new ResponsiveTableSizes([ + new ResponsiveColumnSizes(2, 2, 3, 4, 4), + new ResponsiveColumnSizes(2, 3, 3, 3, 3), + new ResponsiveColumnSizes(2, 2, 2, 2, 2), + new ResponsiveColumnSizes(6, 5, 4, 3, 3) + ]); + const item = Object.assign(new Item(), { id: 'item-1', uuid: 'item-1' @@ -35,6 +44,7 @@ describe('ItemEditBitstreamBundleComponent', () => { comp = fixture.componentInstance; comp.item = item; comp.bundle = bundle; + comp.columnSizes = columnSizes; viewContainerRef = (comp as any).viewContainerRef; spyOn(viewContainerRef, 'createEmbeddedView'); fixture.detectChanges(); diff --git a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index c8e12d53b9..bbf896e5cd 100644 --- a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -16,6 +16,8 @@ import { combineLatest as observableCombineLatest } from 'rxjs'; import { hasNoValue, isEmpty } from '../../../../shared/empty.util'; import { PaginatedSearchOptions } from '../../../../shared/search/paginated-search-options.model'; import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model'; +import { ResponsiveColumnSizes } from '../../../../shared/responsive-table-sizes/responsive-column-sizes'; +import { ResponsiveTableSizes } from '../../../../shared/responsive-table-sizes/responsive-table-sizes'; @Component({ selector: 'ds-item-edit-bitstream-bundle', @@ -42,10 +44,22 @@ export class ItemEditBitstreamBundleComponent implements OnInit { */ @Input() item: Item; + /** + * The bootstrap sizes used for the columns within this table + */ + @Input() columnSizes: ResponsiveTableSizes; + + /** + * The bootstrap sizes used for the Bundle Name column + * This column stretches over the first 3 columns and thus is a combination of their sizes processed in ngOnInit + */ + bundleNameColumn: ResponsiveColumnSizes; + constructor(private viewContainerRef: ViewContainerRef) { } ngOnInit(): void { + this.bundleNameColumn = this.columnSizes.combineColumns(0, 2); this.viewContainerRef.createEmbeddedView(this.bundleView); } } diff --git a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html index 451e820325..25941f472e 100644 --- a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html +++ b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html @@ -19,7 +19,8 @@ 'bg-white': updateValue.changeType === undefined }"> + [bundleUrl]="bundle.self" + [columnSizes]="columnSizes">
diff --git a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.spec.ts b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.spec.ts index edb0087b31..dc5c65af30 100644 --- a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.spec.ts @@ -13,6 +13,8 @@ import { BitstreamFormat } from '../../../../../core/shared/bitstream-format.mod import { createPaginatedList, createSuccessfulRemoteDataObject$ } from '../../../../../shared/testing/utils'; import { of as observableOf } from 'rxjs/internal/observable/of'; import { take } from 'rxjs/operators'; +import { ResponsiveTableSizes } from '../../../../../shared/responsive-table-sizes/responsive-table-sizes'; +import { ResponsiveColumnSizes } from '../../../../../shared/responsive-table-sizes/responsive-column-sizes'; describe('PaginatedDragAndDropBitstreamListComponent', () => { let comp: PaginatedDragAndDropBitstreamListComponent; @@ -20,6 +22,13 @@ describe('PaginatedDragAndDropBitstreamListComponent', () => { let objectUpdatesService: ObjectUpdatesService; let bundleService: BundleDataService; + const columnSizes = new ResponsiveTableSizes([ + new ResponsiveColumnSizes(2, 2, 3, 4, 4), + new ResponsiveColumnSizes(2, 3, 3, 3, 3), + new ResponsiveColumnSizes(2, 2, 2, 2, 2), + new ResponsiveColumnSizes(6, 5, 4, 3, 3) + ]); + const bundle = Object.assign(new Bundle(), { id: 'bundle-1', uuid: 'bundle-1', @@ -104,6 +113,7 @@ describe('PaginatedDragAndDropBitstreamListComponent', () => { fixture = TestBed.createComponent(PaginatedDragAndDropBitstreamListComponent); comp = fixture.componentInstance; comp.bundle = bundle; + comp.columnSizes = columnSizes; fixture.detectChanges(); }); diff --git a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.ts b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.ts index 6ca78dbe89..4c52f5f811 100644 --- a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.ts +++ b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.ts @@ -6,6 +6,7 @@ import { ObjectUpdatesService } from '../../../../../core/data/object-updates/ob import { BundleDataService } from '../../../../../core/data/bundle-data.service'; import { switchMap } from 'rxjs/operators'; import { PaginatedSearchOptions } from '../../../../../shared/search/paginated-search-options.model'; +import { ResponsiveTableSizes } from '../../../../../shared/responsive-table-sizes/responsive-table-sizes'; @Component({ selector: 'ds-paginated-drag-and-drop-bitstream-list', @@ -24,6 +25,11 @@ export class PaginatedDragAndDropBitstreamListComponent extends AbstractPaginate */ @Input() bundle: Bundle; + /** + * The bootstrap sizes used for the columns within this table + */ + @Input() columnSizes: ResponsiveTableSizes; + constructor(protected objectUpdatesService: ObjectUpdatesService, protected elRef: ElementRef, protected bundleService: BundleDataService) { diff --git a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.html b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.html index 3ddc10be46..0885fa5c32 100644 --- a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.html +++ b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.html @@ -1,21 +1,21 @@ -
+
{{ bitstream.name }}
-
+
{{ bitstream.description }}
-
+
{{ (format$ | async).shortDescription }}
-
+
; +const columnSizes = new ResponsiveTableSizes([ + new ResponsiveColumnSizes(2, 2, 3, 4, 4), + new ResponsiveColumnSizes(2, 3, 3, 3, 3), + new ResponsiveColumnSizes(2, 2, 2, 2, 2), + new ResponsiveColumnSizes(6, 5, 4, 3, 3) +]); + const format = Object.assign(new BitstreamFormat(), { shortDescription: 'PDF' }); @@ -71,6 +80,7 @@ describe('ItemEditBitstreamComponent', () => { comp = fixture.componentInstance; comp.fieldUpdate = fieldUpdate; comp.bundleUrl = url; + comp.columnSizes = columnSizes; comp.ngOnChanges(undefined); fixture.detectChanges(); }); diff --git a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts index 0b5e7ec2ae..0deaa5b2a9 100644 --- a/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts +++ b/src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts @@ -7,6 +7,7 @@ import { FieldChangeType } from '../../../../core/data/object-updates/object-upd import { Observable } from 'rxjs/internal/Observable'; import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model'; import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators'; +import { ResponsiveTableSizes } from '../../../../shared/responsive-table-sizes/responsive-table-sizes'; @Component({ selector: 'ds-item-edit-bitstream', @@ -33,6 +34,11 @@ export class ItemEditBitstreamComponent implements OnChanges, OnInit { */ @Input() bundleUrl: string; + /** + * The bootstrap sizes used for the columns within this table + */ + @Input() columnSizes: ResponsiveTableSizes; + /** * The bitstream of this field */ diff --git a/src/app/shared/responsive-table-sizes/responsive-column-sizes.spec.ts b/src/app/shared/responsive-table-sizes/responsive-column-sizes.spec.ts new file mode 100644 index 0000000000..843d0f043e --- /dev/null +++ b/src/app/shared/responsive-table-sizes/responsive-column-sizes.spec.ts @@ -0,0 +1,22 @@ +import { ResponsiveColumnSizes } from './responsive-column-sizes'; + +describe('ResponsiveColumnSizes', () => { + const xs = 2; + const sm = 3; + const md = 4; + const lg = 6; + const xl = 8; + const column = new ResponsiveColumnSizes(xs, sm, md, lg, xl); + + describe('buildClasses', () => { + let classes: string; + + beforeEach(() => { + classes = column.buildClasses(); + }); + + it('should return the correct bootstrap classes', () => { + expect(classes).toEqual(`col-${xs} col-sm-${sm} col-md-${md} col-lg-${lg} col-xl-${xl}`); + }); + }); +}); diff --git a/src/app/shared/responsive-table-sizes/responsive-column-sizes.ts b/src/app/shared/responsive-table-sizes/responsive-column-sizes.ts new file mode 100644 index 0000000000..84651f3ef5 --- /dev/null +++ b/src/app/shared/responsive-table-sizes/responsive-column-sizes.ts @@ -0,0 +1,46 @@ +/** + * A helper class storing the sizes in which to render a single column + * The values in this class are expected to be between 1 and 12 + * There are used to be added to bootstrap classes such as col-xs-{this.xs} + */ +export class ResponsiveColumnSizes { + /** + * The extra small bootstrap size + */ + xs: number; + + /** + * The small bootstrap size + */ + sm: number; + + /** + * The medium bootstrap size + */ + md: number; + + /** + * The large bootstrap size + */ + lg: number; + + /** + * The extra large bootstrap size + */ + xl: number; + + constructor(xs: number, sm: number, md: number, lg: number, xl: number) { + this.xs = xs; + this.sm = sm; + this.md = md; + this.lg = lg; + this.xl = xl; + } + + /** + * Build the bootstrap responsive column classes matching the values of this object + */ + buildClasses(): string { + return `col-${this.xs} col-sm-${this.sm} col-md-${this.md} col-lg-${this.lg} col-xl-${this.xl}` + } +} diff --git a/src/app/shared/responsive-table-sizes/responsive-table-sizes.spec.ts b/src/app/shared/responsive-table-sizes/responsive-table-sizes.spec.ts new file mode 100644 index 0000000000..23df9b1c25 --- /dev/null +++ b/src/app/shared/responsive-table-sizes/responsive-table-sizes.spec.ts @@ -0,0 +1,76 @@ +import { ResponsiveColumnSizes } from './responsive-column-sizes'; +import { ResponsiveTableSizes } from './responsive-table-sizes'; + +describe('ResponsiveColumnSizes', () => { + const column0 = new ResponsiveColumnSizes(2, 3, 4, 6, 8); + const column1 = new ResponsiveColumnSizes(8, 7, 4, 2, 1); + const column2 = new ResponsiveColumnSizes(1, 1, 4, 2, 1); + const column3 = new ResponsiveColumnSizes(1, 1, 4, 2, 2); + const table = new ResponsiveTableSizes([column0, column1, column2, column3]); + + describe('combineColumns', () => { + describe('when start value is out of bounds', () => { + let combined: ResponsiveColumnSizes; + + beforeEach(() => { + combined = table.combineColumns(-1, 2); + }); + + it('should return undefined', () => { + expect(combined).toBeUndefined(); + }); + }); + + describe('when end value is out of bounds', () => { + let combined: ResponsiveColumnSizes; + + beforeEach(() => { + combined = table.combineColumns(0, 5); + }); + + it('should return undefined', () => { + expect(combined).toBeUndefined(); + }); + }); + + describe('when start value is greater than end value', () => { + let combined: ResponsiveColumnSizes; + + beforeEach(() => { + combined = table.combineColumns(2, 0); + }); + + it('should return undefined', () => { + expect(combined).toBeUndefined(); + }); + }); + + describe('when start value is equal to end value', () => { + let combined: ResponsiveColumnSizes; + + beforeEach(() => { + combined = table.combineColumns(0, 0); + }); + + it('should return undefined', () => { + expect(combined).toBeUndefined(); + }); + }); + + describe('when provided with valid values', () => { + let combined: ResponsiveColumnSizes; + + beforeEach(() => { + combined = table.combineColumns(0, 2); + }); + + it('should combine the sizes of each column within the range into one', () => { + expect(combined.xs).toEqual(column0.xs + column1.xs + column2.xs); + expect(combined.sm).toEqual(column0.sm + column1.sm + column2.sm); + expect(combined.md).toEqual(column0.md + column1.md + column2.md); + expect(combined.lg).toEqual(column0.lg + column1.lg + column2.lg); + expect(combined.xl).toEqual(column0.xl + column1.xl + column2.xl); + }); + }); + }); +}); diff --git a/src/app/shared/responsive-table-sizes/responsive-table-sizes.ts b/src/app/shared/responsive-table-sizes/responsive-table-sizes.ts new file mode 100644 index 0000000000..b68774d46f --- /dev/null +++ b/src/app/shared/responsive-table-sizes/responsive-table-sizes.ts @@ -0,0 +1,42 @@ +import { ResponsiveColumnSizes } from './responsive-column-sizes'; +import { hasValue } from '../empty.util'; + +/** + * A helper class storing the sizes in which to render a table + * It stores a list of columns, which in turn store their own bootstrap column sizes + */ +export class ResponsiveTableSizes { + /** + * A list of all the columns and their responsive sizes within this table + */ + columns: ResponsiveColumnSizes[]; + + constructor(columns: ResponsiveColumnSizes[]) { + this.columns = columns; + } + + /** + * Combine the values of multiple columns into a single ResponsiveColumnSizes + * Useful when a row element stretches over multiple columns + * @param start Index of the first column + * @param end Index of the last column (inclusive) + */ + combineColumns(start: number, end: number): ResponsiveColumnSizes { + if (start < end && hasValue(this.columns[start]) && hasValue(this.columns[end])) { + let xs = this.columns[start].xs; + let sm = this.columns[start].sm; + let md = this.columns[start].md; + let lg = this.columns[start].lg; + let xl = this.columns[start].xl; + for (let i = start + 1; i < end + 1; i++) { + xs += this.columns[i].xs; + sm += this.columns[i].sm; + md += this.columns[i].md; + lg += this.columns[i].lg; + xl += this.columns[i].xl; + } + return new ResponsiveColumnSizes(xs, sm, md, lg, xl); + } + return undefined; + } +}