From b6cc7fef5f1fea82c45f3a9929acc36978c540ec Mon Sep 17 00:00:00 2001 From: Abdi Mo Date: Wed, 22 Apr 2026 16:34:57 +0200 Subject: [PATCH 01/11] replaced some old tables with dynamic-mat-table and removed column icons --- .../datafiles/datafiles.component.html | 23 +- .../datafiles/datafiles.component.scss | 3 +- .../datafiles/datafiles.component.spec.ts | 201 +++++------------- .../datasets/datafiles/datafiles.component.ts | 149 +++++-------- .../related-datasets.component.html | 27 +-- .../related-datasets.component.spec.ts | 60 ++++-- .../related-datasets.component.ts | 108 +++++++--- .../files-dashboard.component.ts | 7 - .../instruments-dashboard.component.ts | 2 - .../related-proposals.component.ts | 6 - .../sample-dashboard.component.ts | 5 - 11 files changed, 252 insertions(+), 339 deletions(-) diff --git a/src/app/datasets/datafiles/datafiles.component.html b/src/app/datasets/datafiles/datafiles.component.html index 50ec74edd9..b73f7745eb 100644 --- a/src/app/datasets/datafiles/datafiles.component.html +++ b/src/app/datasets/datafiles/datafiles.component.html @@ -13,7 +13,7 @@ - +
Selected: {{ selectedFileSize | filesize @@ -38,17 +38,16 @@

No files associated to this dataset

>
- - + diff --git a/src/app/datasets/datafiles/datafiles.component.scss b/src/app/datasets/datafiles/datafiles.component.scss index f0663d1d2d..4603154c33 100644 --- a/src/app/datasets/datafiles/datafiles.component.scss +++ b/src/app/datasets/datafiles/datafiles.component.scss @@ -8,7 +8,8 @@ mat-icon { .datafiles-header { margin-top: 1em; - height: 40px; + min-height: 40px; + display: flow-root; .nbr-of-files { font-size: larger; diff --git a/src/app/datasets/datafiles/datafiles.component.spec.ts b/src/app/datasets/datafiles/datafiles.component.spec.ts index c1c843e6d1..0edc325c55 100644 --- a/src/app/datasets/datafiles/datafiles.component.spec.ts +++ b/src/app/datasets/datafiles/datafiles.component.spec.ts @@ -6,14 +6,12 @@ import { MatTableModule } from "@angular/material/table"; import { PipesModule } from "shared/pipes/pipes.module"; import { RouterModule } from "@angular/router"; import { StoreModule } from "@ngrx/store"; -import { CheckboxEvent } from "shared/modules/table/table.component"; import { MockAuthService, MockDatafilesActionsComponent, MockMatDialogRef, MockUserApi, } from "shared/MockStubs"; -import { MatCheckboxChange } from "@angular/material/checkbox"; import { MatIconModule } from "@angular/material/icon"; import { MatButtonModule } from "@angular/material/button"; import { AppConfigService } from "app-config.service"; @@ -22,12 +20,15 @@ import { ConfigurableActionsComponent } from "shared/modules/configurable-action import { UsersService } from "@scicatproject/scicat-sdk-ts-angular"; import { AuthService } from "shared/services/auth/auth.service"; import { FileSizePipe } from "shared/pipes/filesize.pipe"; +import { RowEventType } from "shared/modules/dynamic-material-table/models/table-row.model"; describe("DatafilesComponent", () => { let component: DatafilesComponent; let fixture: ComponentFixture; const getConfig = () => ({ + fileDownloadEnabled: true, + multipleDownloadEnabled: true, datafilesActionsEnabled: true, datafilesActions: [ { @@ -92,6 +93,7 @@ describe("DatafilesComponent", () => { ], declarations: [DatafilesComponent], }); + TestBed.overrideComponent(DatafilesComponent, { set: { providers: [ @@ -107,20 +109,14 @@ describe("DatafilesComponent", () => { ], }, }); + TestBed.compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(DatafilesComponent); component = fixture.componentInstance; - fixture.detectChanges(); - }); - afterEach(() => { - fixture.destroy(); - }); - - beforeEach(() => { component.files = [ { path: "test1", @@ -145,182 +141,93 @@ describe("DatafilesComponent", () => { hash: "", }, ]; - component.tableData = component.files; + component.sourceFolder = "/test/"; fixture.detectChanges(); }); - it("should create", () => { - expect(component).toBeTruthy(); - }); - - describe("#getAreAllSelected()", () => { - it("should return 'false' if no file is selected", () => { - const areAllSelected = component.getAreAllSelected(); - - expect(areAllSelected).toEqual(false); - }); - - it("should return 'false' if only some files are selected", () => { - component.tableData[0].selected = true; - const areAllSelected = component.getAreAllSelected(); - - expect(areAllSelected).toEqual(false); - }); - - it("should return 'true' if all files are selected", () => { - component.tableData.forEach((file) => { - file.selected = true; - }); - const areAllSelected = component.getAreAllSelected(); - - expect(areAllSelected).toEqual(true); - }); + afterEach(() => { + fixture.destroy(); }); - describe("#getIsNoneSelected()", () => { - it("should return 'true' if no file is selected", () => { - const isNoneSelected = component.getIsNoneSelected(); - - expect(isNoneSelected).toEqual(true); - }); - - it("should return 'false' if some files are selected", () => { - component.tableData[0].selected = true; - const isNoneSelected = component.getIsNoneSelected(); - - expect(isNoneSelected).toEqual(false); - }); - - it("should return 'false' if all files are selected", () => { - component.tableData.forEach((file) => { - file.selected = true; - }); - const isNoneSelected = component.getIsNoneSelected(); - - expect(isNoneSelected).toEqual(false); - }); + it("should create", () => { + expect(component).toBeTruthy(); }); describe("#getAllFiles()", () => { - it("should return an array of file paths of files in table", () => { + it("should return an array of file paths from files", () => { const files = component.getAllFiles(); expect(Array.isArray(files)).toEqual(true); - expect(files.includes("test1")).toEqual(true); - expect(files.includes("test2")).toEqual(true); + expect(files).toEqual(["test1", "test2"]); }); }); describe("#getSelectedFiles()", () => { - it("should return an array of file paths from selected files in table", () => { - component.tableData[0].selected = true; + it("should return selected file paths", () => { + component.files[0].selected = true; const files = component.getSelectedFiles(); - expect(Array.isArray(files)).toEqual(true); - expect(files.includes("test1")).toEqual(true); + expect(files).toEqual(["test1"]); }); }); - describe("#updateSelectionStatus()", () => { - it("should set 'areAllSelected' to false and 'isNoneSelected' to true if no file is selected", () => { - component.updateSelectionStatus(); - - expect(component.areAllSelected).toEqual(false); - expect(component.isNoneSelected).toEqual(true); - }); - - it("should set both 'areAllSelected' and 'isNoneSelected' to false if some files are selected", () => { - component.tableData[0].selected = true; - component.updateSelectionStatus(); - - expect(component.areAllSelected).toEqual(false); - expect(component.isNoneSelected).toEqual(false); - }); + describe("#onRowEvent()", () => { + it("should select one row and update selectedFileSize", () => { + const row = component.files[0]; - it("should set 'areAllSelected' to true and 'isNoneSelected' to false if all files are selected", () => { - component.tableData.forEach((file) => { - file.selected = true; - }); - component.updateSelectionStatus(); + component.onRowEvent({ + event: RowEventType.RowSelectionChange, + sender: { row, checked: true }, + } as any); - expect(component.areAllSelected).toEqual(true); - expect(component.isNoneSelected).toEqual(false); + expect(component.files[0].selected).toEqual(true); + expect(component.selectedFileSize).toEqual(5000); }); - }); - describe("#onSelectOne()", () => { - it("should set 'selected' to true and add the size of the file to 'selectedFileSize'", () => { - const file = component.tableData[0]; - const event = new MatCheckboxChange(); - event.checked = true; - const checkboxEvent: CheckboxEvent = { event, row: file }; - component.onSelectOne(checkboxEvent); + it("should unselect one row and update selectedFileSize", () => { + const row = component.files[0]; + row.selected = true; + component.selectedFileSize = 5000; - expect(component.tableData[0].selected).toEqual(true); - expect(component.selectedFileSize).toEqual(file.size); - }); + component.onRowEvent({ + event: RowEventType.RowSelectionChange, + sender: { row, checked: false }, + } as any); - it("should set 'selected' of the provided file to false and subtract the size of the file from 'selectedFileSize'", () => { - const firstFile = component.tableData[0]; - const event = new MatCheckboxChange(); - event.checked = true; - const firstCheckboxEvent: CheckboxEvent = { event, row: firstFile }; - component.onSelectOne(firstCheckboxEvent); - - expect(component.tableData[0].selected).toEqual(true); - expect(component.selectedFileSize).toEqual(firstFile.size); - - const event2 = new MatCheckboxChange(); - event2.checked = false; - const secondCheckboxEvent: CheckboxEvent = { - event: event2, - row: firstFile, - }; - component.onSelectOne(secondCheckboxEvent); - - expect(component.tableData[0].selected).toEqual(false); + expect(component.files[0].selected).toEqual(false); expect(component.selectedFileSize).toEqual(0); }); - }); - describe("#onSelectAll()", () => { - it("should set 'selected' of all files to true if previously set to false and add the size of the files to 'selectedFileSize'", () => { - const event = { - checked: true, - } as MatCheckboxChange; - component.onSelectAll(event); + it("should apply master selection from selectionModel", () => { + const selectionModel = { + isSelected: (file) => file.path === "test1", + }; - component.tableData.forEach((file) => { - expect(file.selected).toEqual(true); - }); + component.onRowEvent({ + event: RowEventType.MasterSelectionChange, + sender: { selectionModel }, + } as any); - expect(component.selectedFileSize).toEqual(15000); + expect(component.files[0].selected).toEqual(true); + expect(component.files[1].selected).toEqual(false); + expect(component.selectedFileSize).toEqual(5000); }); - it("should set 'selected' of all files to false and subtract the size of the files from 'selectedFileSize'", () => { - const firstEvent = { - checked: true, - } as MatCheckboxChange; - component.onSelectAll(firstEvent); + it("should select all rows in master selection", () => { + const selectionModel = { + isSelected: () => true, + }; - component.tableData.forEach((file) => { - expect(file.selected).toEqual(true); - }); + component.onRowEvent({ + event: RowEventType.MasterSelectionChange, + sender: { selectionModel }, + } as any); + expect(component.files[0].selected).toEqual(true); + expect(component.files[1].selected).toEqual(true); expect(component.selectedFileSize).toEqual(15000); - - const secondEvent = { - checked: false, - } as MatCheckboxChange; - component.onSelectAll(secondEvent); - - component.tableData.forEach((file) => { - expect(file.selected).toEqual(false); - }); - - expect(component.selectedFileSize).toEqual(0); }); }); diff --git a/src/app/datasets/datafiles/datafiles.component.ts b/src/app/datasets/datafiles/datafiles.component.ts index 8766755f17..9bd78954c2 100644 --- a/src/app/datasets/datafiles/datafiles.component.ts +++ b/src/app/datasets/datafiles/datafiles.component.ts @@ -8,17 +8,12 @@ import { ViewChild, ElementRef, } from "@angular/core"; -import { Subscription } from "rxjs"; +import { BehaviorSubject, Subscription } from "rxjs"; import { Store } from "@ngrx/store"; import { selectCurrentOrigDatablocks, selectCurrentDataset, } from "state-management/selectors/datasets.selectors"; -import { - TableColumn, - PageChangeEvent, - CheckboxEvent, -} from "shared/modules/table/table.component"; import { selectIsLoading, selectIsLoggedIn, @@ -29,7 +24,6 @@ import { CreateJobDtoV3, } from "@scicatproject/scicat-sdk-ts-angular"; import { FileSizePipe } from "shared/pipes/filesize.pipe"; -import { MatCheckboxChange } from "@angular/material/checkbox"; import { MatDialog } from "@angular/material/dialog"; import { PublicDownloadDialogComponent } from "datasets/public-download-dialog/public-download-dialog.component"; import { submitJobAction } from "state-management/actions/jobs.actions"; @@ -41,6 +35,17 @@ import { ActionItems, } from "shared/modules/configurable-actions/configurable-action.interfaces"; import { AuthService } from "shared/services/auth/auth.service"; +import { TableField } from "shared/modules/dynamic-material-table/models/table-field.model"; +import { + TablePagination, + TablePaginationMode, +} from "shared/modules/dynamic-material-table/models/table-pagination.model"; +import { + IRowEvent, + RowEventType, + TableSelectionMode, +} from "shared/modules/dynamic-material-table/models/table-row.model"; +import { ITableSetting } from "shared/modules/dynamic-material-table/models/table-setting.model"; @Component({ selector: "datafiles", @@ -64,9 +69,6 @@ export class DatafilesComponent implements OnDestroy, OnInit, AfterViewChecked { totalFileSize = 0; selectedFileSize = 0; - areAllSelected = false; - isNoneSelected = true; - subscriptions: Subscription[] = []; files: Array = []; @@ -76,8 +78,6 @@ export class DatafilesComponent implements OnDestroy, OnInit, AfterViewChecked { }; count = 0; - pageSize = 25; - currentPage = 0; fileDownloadEnabled: boolean = this.appConfig.fileDownloadEnabled; multipleDownloadEnabled: boolean = this.appConfig.multipleDownloadEnabled; fileserverBaseURL: string | undefined = this.appConfig.fileserverBaseURL; @@ -94,29 +94,47 @@ export class DatafilesComponent implements OnDestroy, OnInit, AfterViewChecked { jwt: CreateUserJWT; auth_token: string; - tableColumns: TableColumn[] = [ + tableColumns: TableField[] = [ { name: "path", - icon: "save", - sort: false, - inList: true, + header: "Path", }, { name: "size", - icon: "save", - sort: false, - inList: true, - pipe: FileSizePipe, + header: "Size", + customRender: (_column, row: DataFiles_File) => + this.fileSizePipe.transform(row.size), }, { name: "time", - icon: "access_time", - sort: false, - inList: true, - dateFormat: "yyyy-MM-dd HH:mm", + header: "Time", + type: "date", + format: "yyyy-MM-dd HH:mm", }, ]; - tableData: DataFiles_File[] = []; + + setting: ITableSetting = { + rowStyle: { + "border-bottom": "1px solid #d2d2d2", + }, + }; + + dataSource: BehaviorSubject = new BehaviorSubject< + DataFiles_File[] + >([]); + + paginationMode: TablePaginationMode = "server-side"; + + pagination: TablePagination = { + pageSizeOptions: [10, 25, 50], + pageIndex: 0, + pageSize: 25, + length: 0, + }; + + rowSelectionMode: TableSelectionMode = this.fileDownloadEnabled + ? "multi" + : "none"; constructor( public appConfigService: AppConfigService, @@ -128,80 +146,28 @@ export class DatafilesComponent implements OnDestroy, OnInit, AfterViewChecked { private fileSizePipe: FileSizePipe, ) {} - onPageChange(event: PageChangeEvent) { - const { pageIndex, pageSize } = event; - this.currentPage = pageIndex; - this.pageSize = pageSize; - const skip = this.currentPage * this.pageSize; - const end = skip + this.pageSize; - this.tableData = this.files.slice(skip, end); - } - - getAreAllSelected() { - return this.tableData.reduce((accum, curr) => accum && curr.selected, true); - } - - getIsNoneSelected() { - return this.tableData.reduce( - (accum, curr) => accum && !curr.selected, - true, - ); - } - getAllFiles() { - if (!this.tableData) { - return []; - } - return this.tableData.map((file) => file.path); + return this.files.map((file) => file.path); } getSelectedFiles() { - if (!this.tableData) { - return []; - } - return this.tableData - .filter((file) => file.selected) - .map((file) => file.path); - } - - updateSelectionStatus() { - this.areAllSelected = this.getAreAllSelected(); - this.isNoneSelected = this.getIsNoneSelected(); - this.updateSelectedInFiles(); + return this.files.filter((file) => file.selected).map((file) => file.path); } - updateSelectedInFiles() { - const selected = this.tableData - .filter((item) => item.selected) - .map((item) => item.path); - const files = this.files.map((item) => { - item.selected = selected.includes(item.path); - return item; - }); - this.files = [...files]; - } + onRowEvent({ event, sender }: IRowEvent) { + if (event === RowEventType.RowSelectionChange && sender.row) { + sender.row.selected = sender.checked; + } - onSelectOne(checkboxEvent: CheckboxEvent) { - const { event, row } = checkboxEvent; - row.selected = event.checked; - if (event.checked) { - this.selectedFileSize += row.size; - } else { - this.selectedFileSize -= row.size; + if (event === RowEventType.MasterSelectionChange && sender.selectionModel) { + this.files.forEach((file) => { + file.selected = sender.selectionModel.isSelected(file); + }); } - this.updateSelectionStatus(); - } - onSelectAll(event: MatCheckboxChange) { - this.tableData.forEach((file) => { - file.selected = event.checked; - if (event.checked) { - this.selectedFileSize += file.size; - } else { - this.selectedFileSize = 0; - } - }); - this.updateSelectionStatus(); + this.selectedFileSize = this.files + .filter((file) => file.selected) + .reduce((sum, file) => sum + file.size, 0); } hasTooLargeFiles(files: any[]) { @@ -268,8 +234,9 @@ export class DatafilesComponent implements OnDestroy, OnInit, AfterViewChecked { }); }); this.count = files.length; - this.tableData = files.slice(0, this.pageSize); this.files = files; + this.dataSource.next(files); + this.pagination.length = files.length; this.tooLargeFile = this.hasTooLargeFiles(this.files); this.actionItems.datasets[0].files = files; } diff --git a/src/app/datasets/related-datasets/related-datasets.component.html b/src/app/datasets/related-datasets/related-datasets.component.html index fe0d5f231f..458faee54c 100644 --- a/src/app/datasets/related-datasets/related-datasets.component.html +++ b/src/app/datasets/related-datasets/related-datasets.component.html @@ -1,19 +1,14 @@
- - - - + [setting]="setting" + [dataSource]="dataSource" + [pagination]="pagination" + [pagingMode]="paginationMode" + [showGlobalTextSearch]="false" + [rowSelectionMode]="rowSelectionMode" + [emptyMessage]="'No related datasets available'" + (paginationChange)="onPaginationChange($event)" + (onRowEvent)="onRowEvent($event)" + >
diff --git a/src/app/datasets/related-datasets/related-datasets.component.spec.ts b/src/app/datasets/related-datasets/related-datasets.component.spec.ts index 71c4e47887..4a5bb93e1a 100644 --- a/src/app/datasets/related-datasets/related-datasets.component.spec.ts +++ b/src/app/datasets/related-datasets/related-datasets.component.spec.ts @@ -1,20 +1,27 @@ import { DatePipe } from "@angular/common"; import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { Router } from "@angular/router"; +import { ActivatedRoute, Router } from "@angular/router"; import { Store } from "@ngrx/store"; import { provideMockStore } from "@ngrx/store/testing"; -import { PageChangeEvent } from "shared/modules/table/table.component"; import { changeRelatedDatasetsPageAction, fetchRelatedDatasetsAction, } from "state-management/actions/datasets.actions"; -import { selectRelatedDatasetsPageViewModel } from "state-management/selectors/datasets.selectors"; +import { + selectRelatedDatasetsCurrentPage, + selectRelatedDatasetsPageViewModel, + selectRelatedDatasetsPerPage, +} from "state-management/selectors/datasets.selectors"; import { RelatedDatasetsComponent } from "./related-datasets.component"; -import { TableModule } from "shared/modules/table/table.module"; -import { createMock } from "shared/MockStubs"; +import { MockActivatedRoute, createMock } from "shared/MockStubs"; import { DatasetClass } from "@scicatproject/scicat-sdk-ts-angular"; -import { EmptyContentModule } from "shared/modules/generic-empty-content/empty-content.module"; +import { RowEventType } from "shared/modules/dynamic-material-table/models/table-row.model"; +import { DynamicMatTableModule } from "shared/modules/dynamic-material-table/table/dynamic-mat-table.module"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { TranslateService } from "@ngx-translate/core"; +import { SharedScicatFrontendModule } from "shared/shared.module"; +import { TablePagination } from "shared/modules/dynamic-material-table/models/table-pagination.model"; describe("RelatedDatasetsComponent", () => { let component: RelatedDatasetsComponent; @@ -22,14 +29,19 @@ describe("RelatedDatasetsComponent", () => { const router = { navigateByUrl: jasmine.createSpy("navigateByUrl"), + navigate: jasmine.createSpy("navigate"), }; let store: Store; - let dispatchSpy; + let dispatchSpy: jasmine.Spy; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [RelatedDatasetsComponent], - imports: [TableModule, EmptyContentModule], + imports: [ + BrowserAnimationsModule, + DynamicMatTableModule.forRoot({}), + SharedScicatFrontendModule, + ], providers: [ DatePipe, provideMockStore({ @@ -39,16 +51,21 @@ describe("RelatedDatasetsComponent", () => { value: { relatedDatasets: [], relatedDatasetsCount: 0, - relatedDatasetsFilters: { - skip: 0, - limit: 25, - sortField: "creationTime:desc", - }, }, }, + { + selector: selectRelatedDatasetsCurrentPage, + value: 0, + }, + { + selector: selectRelatedDatasetsPerPage, + value: 25, + }, ], }), { provide: Router, useValue: router }, + { provide: ActivatedRoute, useClass: MockActivatedRoute }, + { provide: TranslateService, useValue: { instant: (k: string) => k } }, ], }).compileComponents(); @@ -65,17 +82,17 @@ describe("RelatedDatasetsComponent", () => { expect(component).toBeTruthy(); }); - describe("#onPageChange", () => { - it("should dispatch a changeRelatedDatasetsPageAction and a fetchRelatedDatasetsAction", () => { + describe("#onPaginationChange()", () => { + it("should dispatch changeRelatedDatasetsPageAction and fetchRelatedDatasetsAction", () => { dispatchSpy = spyOn(store, "dispatch"); - const event: PageChangeEvent = { + const event: TablePagination = { pageIndex: 0, pageSize: 25, length: 25, }; - component.onPageChange(event); + component.onPaginationChange(event); expect(dispatchSpy).toHaveBeenCalledTimes(2); expect(dispatchSpy).toHaveBeenCalledWith( @@ -88,11 +105,14 @@ describe("RelatedDatasetsComponent", () => { }); }); - describe("#onRowClick()", () => { + describe("#onRowEvent()", () => { it("should navigate to a dataset", () => { - const dataset = createMock({}); + const dataset = createMock({ pid: "PID-123" }); - component.onRowClick(dataset); + component.onRowEvent({ + event: RowEventType.RowClick, + sender: { row: dataset }, + } as any); expect(router.navigateByUrl).toHaveBeenCalledOnceWith( "/datasets/" + encodeURIComponent(dataset.pid), diff --git a/src/app/datasets/related-datasets/related-datasets.component.ts b/src/app/datasets/related-datasets/related-datasets.component.ts index 750e0f5d09..3d8d5c971c 100644 --- a/src/app/datasets/related-datasets/related-datasets.component.ts +++ b/src/app/datasets/related-datasets/related-datasets.component.ts @@ -1,12 +1,8 @@ import { DatePipe } from "@angular/common"; -import { Component } from "@angular/core"; +import { Component, OnInit, OnDestroy } from "@angular/core"; import { Router } from "@angular/router"; import { Store } from "@ngrx/store"; import { map } from "rxjs/operators"; -import { - PageChangeEvent, - TableColumn, -} from "shared/modules/table/table.component"; import { DatasetClass, OutputDatasetObsoleteDto, @@ -20,6 +16,18 @@ import { selectRelatedDatasetsPageViewModel, selectRelatedDatasetsPerPage, } from "state-management/selectors/datasets.selectors"; +import { TableField } from "shared/modules/dynamic-material-table/models/table-field.model"; +import { BehaviorSubject, Subscription } from "rxjs"; +import { + TablePagination, + TablePaginationMode, +} from "shared/modules/dynamic-material-table/models/table-pagination.model"; +import { + IRowEvent, + RowEventType, + TableSelectionMode, +} from "shared/modules/dynamic-material-table/models/table-row.model"; +import { ITableSetting } from "shared/modules/dynamic-material-table/models/table-setting.model"; @Component({ selector: "app-related-datasets", @@ -27,7 +35,7 @@ import { styleUrls: ["./related-datasets.component.scss"], standalone: false, }) -export class RelatedDatasetsComponent { +export class RelatedDatasetsComponent implements OnInit, OnDestroy { vm$ = this.store.select(selectRelatedDatasetsPageViewModel).pipe( map((vm) => ({ ...vm, @@ -37,52 +45,86 @@ export class RelatedDatasetsComponent { currentPage$ = this.store.select(selectRelatedDatasetsCurrentPage); datasetsPerPage$ = this.store.select(selectRelatedDatasetsPerPage); - tablePaginate = true; - tableColumns: TableColumn[] = [ + subscriptions: Subscription[] = []; + + tableColumns: TableField[] = [ { name: "name", - icon: "portrait", - sort: true, - inList: true, + header: "Name", }, { name: "sourceFolder", - icon: "explore", - sort: true, - inList: true, + header: "Source Folder", }, { name: "size", - icon: "save", - sort: true, - inList: true, + header: "Size", }, { name: "type", - icon: "bubble_chart", - sort: true, - inList: true, + header: "Type", }, { name: "creationTime", - icon: "calendar_today", - sort: true, - inList: true, + header: "Creation Time", }, { name: "owner", - icon: "face", - sort: true, - inList: true, + header: "Owner", }, ]; + setting: ITableSetting = { + rowStyle: { + "border-bottom": "1px solid #d2d2d2", + }, + }; + + dataSource: BehaviorSubject = new BehaviorSubject([]); + + paginationMode: TablePaginationMode = "server-side"; + + pagination: TablePagination = { + pageSizeOptions: [5, 10, 25, 50, 100], + pageIndex: 0, + pageSize: 10, + length: 0, + }; + + rowSelectionMode: TableSelectionMode = "none"; + constructor( private datePipe: DatePipe, private router: Router, private store: Store, ) {} + ngOnInit(): void { + this.subscriptions.push( + this.vm$.subscribe((vm) => { + this.dataSource.next(vm.relatedDatasets); + this.pagination.length = vm.relatedDatasetsCount || 0; + }), + ); + + this.subscriptions.push( + this.datasetsPerPage$.subscribe((size) => { + const pageSize = size || 25; + this.pagination.pageSize = pageSize; + if (!this.pagination.pageSizeOptions.includes(pageSize)) { + this.pagination.pageSizeOptions = [ + ...this.pagination.pageSizeOptions, + pageSize, + ].sort((a, b) => a - b); + } + }), + ); + } + + ngOnDestroy(): void { + this.subscriptions.forEach((s) => s.unsubscribe()); + } + formatTableData( datasets: OutputDatasetObsoleteDto[], ): Record[] { @@ -104,18 +146,20 @@ export class RelatedDatasetsComponent { })); } - onPageChange(event: PageChangeEvent): void { + onPaginationChange({ pageIndex, pageSize }: TablePagination): void { this.store.dispatch( changeRelatedDatasetsPageAction({ - page: event.pageIndex, - limit: event.pageSize, + page: pageIndex, + limit: pageSize, }), ); this.store.dispatch(fetchRelatedDatasetsAction()); } - onRowClick(dataset: DatasetClass): void { - const pid = encodeURIComponent(dataset.pid); - this.router.navigateByUrl("/datasets/" + pid); + onRowEvent({ event, sender }: IRowEvent): void { + if (event === RowEventType.RowClick) { + const pid = encodeURIComponent(sender.row.pid); + this.router.navigateByUrl("/datasets/" + pid); + } } } diff --git a/src/app/files/files-dashboard/files-dashboard.component.ts b/src/app/files/files-dashboard/files-dashboard.component.ts index 5473fc45e2..b097853e20 100644 --- a/src/app/files/files-dashboard/files-dashboard.component.ts +++ b/src/app/files/files-dashboard/files-dashboard.component.ts @@ -73,7 +73,6 @@ export class FilesDashboardComponent implements OnInit, OnDestroy { columnSetting: [ { name: "dataFileList.path", - icon: "text_snippet", header: "Filename", customRender(column, row) { return get(row, column.name); @@ -81,7 +80,6 @@ export class FilesDashboardComponent implements OnInit, OnDestroy { }, { name: "dataFileList.size", - icon: "save", header: "Size", customRender(column, row) { return get(row, column.name); @@ -89,7 +87,6 @@ export class FilesDashboardComponent implements OnInit, OnDestroy { }, { name: "dataFileList.time", - icon: "access_time", header: "Created at", customRender: (column, row) => { return this.datePipe.transform(get(row, column.name)); @@ -97,7 +94,6 @@ export class FilesDashboardComponent implements OnInit, OnDestroy { }, { name: "dataFileList.uid", - icon: "person", header: "UID", customRender: (column, row) => { return get(row, column.name); @@ -105,7 +101,6 @@ export class FilesDashboardComponent implements OnInit, OnDestroy { }, { name: "dataFileList.gid", - icon: "group", header: "GID", customRender: (column, row) => { return get(row, column.name); @@ -113,12 +108,10 @@ export class FilesDashboardComponent implements OnInit, OnDestroy { }, { name: "ownerGroup", - icon: "group", header: "Owner Group", }, { name: "datasetId", - icon: "list", header: "Dataset PID", customRender: (column, row) => `${row[column.name]}`, diff --git a/src/app/instruments/instruments-dashboard/instruments-dashboard.component.ts b/src/app/instruments/instruments-dashboard/instruments-dashboard.component.ts index 5c7c418e07..b4a98e0923 100644 --- a/src/app/instruments/instruments-dashboard/instruments-dashboard.component.ts +++ b/src/app/instruments/instruments-dashboard/instruments-dashboard.component.ts @@ -37,12 +37,10 @@ const tableDefaultSettingsConfig: ITableSetting = { { name: "uniqueName", header: "Unique Name", - icon: "scanner", }, { name: "name", header: "Name", - icon: "fingerprint", }, ], }, diff --git a/src/app/proposals/related-proposals/related-proposals.component.ts b/src/app/proposals/related-proposals/related-proposals.component.ts index 638c566e78..05667ca7d5 100644 --- a/src/app/proposals/related-proposals/related-proposals.component.ts +++ b/src/app/proposals/related-proposals/related-proposals.component.ts @@ -39,27 +39,21 @@ const tableDefaultSettingsConfig: ITableSetting = { { name: "proposalId", header: "Proposal ID", - icon: "perm_device_information", }, { name: "relation", - icon: "compare_arrows", }, { name: "title", - icon: "description", }, { name: "abstract", - icon: "description", }, { name: "email", - icon: "badge", }, { name: "type", - icon: "text_format", }, ], }, diff --git a/src/app/samples/sample-dashboard/sample-dashboard.component.ts b/src/app/samples/sample-dashboard/sample-dashboard.component.ts index 326bbde27b..8e915e58cd 100644 --- a/src/app/samples/sample-dashboard/sample-dashboard.component.ts +++ b/src/app/samples/sample-dashboard/sample-dashboard.component.ts @@ -71,21 +71,17 @@ export class SampleDashboardComponent implements OnInit, OnDestroy { columnSetting: [ { name: "sampleId", - icon: "fingerprint", header: "Sample ID", }, { name: "description", - icon: "description", }, { name: "owner", - icon: "face", }, { name: "createdAt", header: "Creation time", - icon: "date_range", customRender: (column, row) => { return this.datePipe.transform(row[column.name]); }, @@ -93,7 +89,6 @@ export class SampleDashboardComponent implements OnInit, OnDestroy { { name: "ownerGroup", header: "Owner group", - icon: "group", }, ], }, From 961274c26ec3fe0b64038f04c62fa2c55a9f80d4 Mon Sep 17 00:00:00 2001 From: Abdi Mo Date: Mon, 27 Apr 2026 13:59:41 +0200 Subject: [PATCH 02/11] sourcery changes --- .../datafiles/datafiles.component.html | 1 + .../datasets/datafiles/datafiles.component.ts | 36 ++++++++++++++++--- .../related-datasets.component.ts | 9 +++-- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/app/datasets/datafiles/datafiles.component.html b/src/app/datasets/datafiles/datafiles.component.html index b73f7745eb..bfdb646436 100644 --- a/src/app/datasets/datafiles/datafiles.component.html +++ b/src/app/datasets/datafiles/datafiles.component.html @@ -48,6 +48,7 @@

No files associated to this dataset

[rowSelectionMode]="rowSelectionMode" [emptyMessage]="'No datafiles available'" (onRowEvent)="onRowEvent($event)" + (paginationChange)="onPaginationChange($event)" > diff --git a/src/app/datasets/datafiles/datafiles.component.ts b/src/app/datasets/datafiles/datafiles.component.ts index 9bd78954c2..4347f31700 100644 --- a/src/app/datasets/datafiles/datafiles.component.ts +++ b/src/app/datasets/datafiles/datafiles.component.ts @@ -123,10 +123,10 @@ export class DatafilesComponent implements OnDestroy, OnInit, AfterViewChecked { DataFiles_File[] >([]); - paginationMode: TablePaginationMode = "server-side"; + paginationMode: TablePaginationMode = "client-side"; pagination: TablePagination = { - pageSizeOptions: [10, 25, 50], + pageSizeOptions: [5, 10, 25, 50, 100], pageIndex: 0, pageSize: 25, length: 0, @@ -225,6 +225,7 @@ export class DatafilesComponent implements OnDestroy, OnInit, AfterViewChecked { this.subscriptions.push( this.datablocks$.subscribe((datablocks) => { if (datablocks) { + this.totalFileSize = 0; const files: DataFiles_File[] = []; datablocks.forEach((block) => { block.dataFileList.map((file: DataFiles_File) => { @@ -235,10 +236,19 @@ export class DatafilesComponent implements OnDestroy, OnInit, AfterViewChecked { }); this.count = files.length; this.files = files; - this.dataSource.next(files); - this.pagination.length = files.length; + + this.pagination = { + ...this.pagination, + pageIndex: 0, + length: files.length, + pageSize: this.pagination.pageSize || 25, + }; + + this.applyPagination(); this.tooLargeFile = this.hasTooLargeFiles(this.files); - this.actionItems.datasets[0].files = files; + if (this.actionItems.datasets.length > 0) { + this.actionItems.datasets[0].files = files; + } } }), ); @@ -266,6 +276,22 @@ export class DatafilesComponent implements OnDestroy, OnInit, AfterViewChecked { } } + applyPagination() { + const start = this.pagination.pageIndex * this.pagination.pageSize; + const end = start + this.pagination.pageSize; + this.dataSource.next(this.files.slice(start, end)); + } + + onPaginationChange({ pageIndex, pageSize }: TablePagination) { + this.pagination = { + ...this.pagination, + pageIndex, + pageSize, + length: this.files.length, + }; + this.applyPagination(); + } + ngOnDestroy() { this.subscriptions.forEach((subscription) => subscription.unsubscribe()); } diff --git a/src/app/datasets/related-datasets/related-datasets.component.ts b/src/app/datasets/related-datasets/related-datasets.component.ts index 3d8d5c971c..ee0a5fefe8 100644 --- a/src/app/datasets/related-datasets/related-datasets.component.ts +++ b/src/app/datasets/related-datasets/related-datasets.component.ts @@ -80,7 +80,9 @@ export class RelatedDatasetsComponent implements OnInit, OnDestroy { }, }; - dataSource: BehaviorSubject = new BehaviorSubject([]); + dataSource: BehaviorSubject = new BehaviorSubject< + OutputDatasetObsoleteDto[] + >([]); paginationMode: TablePaginationMode = "server-side"; @@ -127,12 +129,13 @@ export class RelatedDatasetsComponent implements OnInit, OnDestroy { formatTableData( datasets: OutputDatasetObsoleteDto[], - ): Record[] { + ): OutputDatasetObsoleteDto[] { if (!datasets) { return []; } return datasets.map((dataset) => ({ + ...dataset, pid: dataset.pid, name: dataset.datasetName, sourceFolder: dataset.sourceFolder, @@ -156,7 +159,7 @@ export class RelatedDatasetsComponent implements OnInit, OnDestroy { this.store.dispatch(fetchRelatedDatasetsAction()); } - onRowEvent({ event, sender }: IRowEvent): void { + onRowEvent({ event, sender }: IRowEvent): void { if (event === RowEventType.RowClick) { const pid = encodeURIComponent(sender.row.pid); this.router.navigateByUrl("/datasets/" + pid); From 669c7e5de94e8576c88da37876fac9e82ae99d9c Mon Sep 17 00:00:00 2001 From: Abdi Mo Date: Mon, 27 Apr 2026 14:09:24 +0200 Subject: [PATCH 03/11] test fix: added provider for HttpClient --- .../related-datasets/related-datasets.component.spec.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/datasets/related-datasets/related-datasets.component.spec.ts b/src/app/datasets/related-datasets/related-datasets.component.spec.ts index 4a5bb93e1a..53a32a6bc0 100644 --- a/src/app/datasets/related-datasets/related-datasets.component.spec.ts +++ b/src/app/datasets/related-datasets/related-datasets.component.spec.ts @@ -22,6 +22,8 @@ import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { TranslateService } from "@ngx-translate/core"; import { SharedScicatFrontendModule } from "shared/shared.module"; import { TablePagination } from "shared/modules/dynamic-material-table/models/table-pagination.model"; +import { provideHttpClient, withInterceptorsFromDi } from "@angular/common/http"; +import { provideHttpClientTesting } from "@angular/common/http/testing"; describe("RelatedDatasetsComponent", () => { let component: RelatedDatasetsComponent; @@ -66,6 +68,8 @@ describe("RelatedDatasetsComponent", () => { { provide: Router, useValue: router }, { provide: ActivatedRoute, useClass: MockActivatedRoute }, { provide: TranslateService, useValue: { instant: (k: string) => k } }, + provideHttpClient(withInterceptorsFromDi()), + provideHttpClientTesting(), ], }).compileComponents(); From fa9e3a2cb27c00b0c1bc3e0314bb315930ae57c7 Mon Sep 17 00:00:00 2001 From: Abdi Mo Date: Mon, 27 Apr 2026 14:12:58 +0200 Subject: [PATCH 04/11] eslint fix --- .../related-datasets/related-datasets.component.spec.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/datasets/related-datasets/related-datasets.component.spec.ts b/src/app/datasets/related-datasets/related-datasets.component.spec.ts index 53a32a6bc0..20eb7f6f1f 100644 --- a/src/app/datasets/related-datasets/related-datasets.component.spec.ts +++ b/src/app/datasets/related-datasets/related-datasets.component.spec.ts @@ -22,7 +22,10 @@ import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { TranslateService } from "@ngx-translate/core"; import { SharedScicatFrontendModule } from "shared/shared.module"; import { TablePagination } from "shared/modules/dynamic-material-table/models/table-pagination.model"; -import { provideHttpClient, withInterceptorsFromDi } from "@angular/common/http"; +import { + provideHttpClient, + withInterceptorsFromDi, +} from "@angular/common/http"; import { provideHttpClientTesting } from "@angular/common/http/testing"; describe("RelatedDatasetsComponent", () => { From b16bc405cc286abd794a53cfccc2ebd42952a0e6 Mon Sep 17 00:00:00 2001 From: Abdi Mo Date: Mon, 27 Apr 2026 14:21:56 +0200 Subject: [PATCH 05/11] test: removed unneeded config options --- src/app/datasets/datafiles/datafiles.component.spec.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/app/datasets/datafiles/datafiles.component.spec.ts b/src/app/datasets/datafiles/datafiles.component.spec.ts index 0edc325c55..499fc909ef 100644 --- a/src/app/datasets/datafiles/datafiles.component.spec.ts +++ b/src/app/datasets/datafiles/datafiles.component.spec.ts @@ -27,8 +27,6 @@ describe("DatafilesComponent", () => { let fixture: ComponentFixture; const getConfig = () => ({ - fileDownloadEnabled: true, - multipleDownloadEnabled: true, datafilesActionsEnabled: true, datafilesActions: [ { From e002fbd74dc09daa6e77345035d8ce67e1272449 Mon Sep 17 00:00:00 2001 From: Abdi Mo Date: Mon, 11 May 2026 10:45:05 +0200 Subject: [PATCH 06/11] added actionMenu for datafiles table --- .../datasets/datafiles/datafiles.component.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/app/datasets/datafiles/datafiles.component.ts b/src/app/datasets/datafiles/datafiles.component.ts index 4347f31700..260d6f3fff 100644 --- a/src/app/datasets/datafiles/datafiles.component.ts +++ b/src/app/datasets/datafiles/datafiles.component.ts @@ -46,6 +46,7 @@ import { TableSelectionMode, } from "shared/modules/dynamic-material-table/models/table-row.model"; import { ITableSetting } from "shared/modules/dynamic-material-table/models/table-setting.model"; +import { actionMenu } from "shared/modules/dynamic-material-table/utilizes/default-table-settings"; @Component({ selector: "datafiles", @@ -113,7 +114,20 @@ export class DatafilesComponent implements OnDestroy, OnInit, AfterViewChecked { }, ]; - setting: ITableSetting = { + setting: ITableSetting = {}; + + tableDefaultSettingsConfig: ITableSetting = { + visibleActionMenu: actionMenu, + saveSettingMode: "none", + settingList: [ + { + visibleActionMenu: actionMenu, + saveSettingMode: "none", + isDefaultSetting: true, + isCurrentSetting: true, + columnSetting: [], + }, + ], rowStyle: { "border-bottom": "1px solid #d2d2d2", }, @@ -215,6 +229,7 @@ export class DatafilesComponent implements OnDestroy, OnInit, AfterViewChecked { } //ngAfterViewInit() { ngOnInit() { + this.setting = this.tableDefaultSettingsConfig; this.subscriptions.push( this.dataset$.subscribe((dataset) => { if (dataset) { From 832a970773f486e62207f822f68d0879b44d0dde Mon Sep 17 00:00:00 2001 From: Abdi Mo Date: Mon, 11 May 2026 12:55:44 +0200 Subject: [PATCH 07/11] synced related datasets table with user column settings --- .../related-datasets.component.html | 3 +- .../related-datasets.component.ts | 117 ++++++++++++++---- 2 files changed, 96 insertions(+), 24 deletions(-) diff --git a/src/app/datasets/related-datasets/related-datasets.component.html b/src/app/datasets/related-datasets/related-datasets.component.html index 458faee54c..fd90610da2 100644 --- a/src/app/datasets/related-datasets/related-datasets.component.html +++ b/src/app/datasets/related-datasets/related-datasets.component.html @@ -1,6 +1,7 @@
[]; + + pending = true; + + setting: ITableSetting = {}; tableColumns: TableField[] = [ { @@ -74,7 +95,18 @@ export class RelatedDatasetsComponent implements OnInit, OnDestroy { }, ]; - setting: ITableSetting = { + tableDefaultSettingsConfig: ITableSetting = { + visibleActionMenu: actionMenu, + saveSettingMode: "none", + settingList: [ + { + visibleActionMenu: actionMenu, + saveSettingMode: "none", + isDefaultSetting: true, + isCurrentSetting: true, + columnSetting: [], + }, + ], rowStyle: { "border-bottom": "1px solid #d2d2d2", }, @@ -99,32 +131,71 @@ export class RelatedDatasetsComponent implements OnInit, OnDestroy { private datePipe: DatePipe, private router: Router, private store: Store, + private appConfigService: AppConfigService, + private tableConfigService: TableConfigService, + private datasetsListService: DatasetsListService, ) {} ngOnInit(): void { - this.subscriptions.push( - this.vm$.subscribe((vm) => { - this.dataSource.next(vm.relatedDatasets); - this.pagination.length = vm.relatedDatasetsCount || 0; - }), - ); + this.store.dispatch(fetchRelatedDatasetsAction()); - this.subscriptions.push( - this.datasetsPerPage$.subscribe((size) => { - const pageSize = size || 25; - this.pagination.pageSize = pageSize; - if (!this.pagination.pageSizeOptions.includes(pageSize)) { - this.pagination.pageSizeOptions = [ - ...this.pagination.pageSizeOptions, - pageSize, - ].sort((a, b) => a - b); - } - }), - ); + this.subscription = combineLatest([ + this.vm$, + this.selectColumnsWithFetchedSettings$.pipe(take(1)), + this.currentPage$, + this.datasetsPerPage$, + ]).subscribe(([vm, defaultTableColumns, currentPage, datasetsPerPage]) => { + this.dataSource.next(vm.relatedDatasets); + this.pending = false; + + const defaultConfigColumns = + this.appConfig?.defaultDatasetsListSettings?.columns || []; + + const userTableConfigColumns = + this.datasetsListService.convertSavedDatasetColumns( + defaultTableColumns.columns, + ); + + this.tableDefaultSettingsConfig.settingList[0].columnSetting = + this.datasetsListService.convertSavedDatasetColumns( + defaultConfigColumns as TableColumn[], + ); + + const tableSettingsConfig = + this.tableConfigService.getTableSettingsConfig( + this.tableName, + this.tableDefaultSettingsConfig, + userTableConfigColumns, + ); + + const paginationConfig = { + pageSizeOptions: [5, 10, 25, 100], + pageIndex: currentPage || 0, + pageSize: datasetsPerPage || 10, + length: vm.relatedDatasetsCount || 0, + }; + + if (tableSettingsConfig?.settingList.length) { + this.initTable(tableSettingsConfig, paginationConfig); + } + }); + } + + initTable( + settingConfig: ITableSetting, + paginationConfig: TablePagination, + ): void { + const currentColumnSetting = settingConfig.settingList.find( + (s) => s.isCurrentSetting, + )?.columnSetting; + + this.columns = currentColumnSetting; + this.setting = settingConfig; + this.pagination = paginationConfig; } ngOnDestroy(): void { - this.subscriptions.forEach((s) => s.unsubscribe()); + this.subscription.unsubscribe(); } formatTableData( From 0b41cfdd2ecc4eefc1dce88b7aaf4ba20fc07896 Mon Sep 17 00:00:00 2001 From: Abdi Mo Date: Mon, 11 May 2026 13:05:18 +0200 Subject: [PATCH 08/11] fixed tests --- .../related-datasets/related-datasets.component.spec.ts | 7 +++++++ .../related-datasets/related-datasets.component.ts | 4 +--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/app/datasets/related-datasets/related-datasets.component.spec.ts b/src/app/datasets/related-datasets/related-datasets.component.spec.ts index 20eb7f6f1f..2781776487 100644 --- a/src/app/datasets/related-datasets/related-datasets.component.spec.ts +++ b/src/app/datasets/related-datasets/related-datasets.component.spec.ts @@ -27,6 +27,8 @@ import { withInterceptorsFromDi, } from "@angular/common/http"; import { provideHttpClientTesting } from "@angular/common/http/testing"; +import { FileSizePipe } from "shared/pipes/filesize.pipe"; +import { selectColumnsWithHasFetchedSettings } from "state-management/selectors/user.selectors"; describe("RelatedDatasetsComponent", () => { let component: RelatedDatasetsComponent; @@ -49,6 +51,7 @@ describe("RelatedDatasetsComponent", () => { ], providers: [ DatePipe, + FileSizePipe, provideMockStore({ selectors: [ { @@ -66,6 +69,10 @@ describe("RelatedDatasetsComponent", () => { selector: selectRelatedDatasetsPerPage, value: 25, }, + { + selector: selectColumnsWithHasFetchedSettings, + value: { columns: [], hasFetchedSettings: true }, + }, ], }), { provide: Router, useValue: router }, diff --git a/src/app/datasets/related-datasets/related-datasets.component.ts b/src/app/datasets/related-datasets/related-datasets.component.ts index 012ef2d97d..2d90e7d185 100644 --- a/src/app/datasets/related-datasets/related-datasets.component.ts +++ b/src/app/datasets/related-datasets/related-datasets.component.ts @@ -3,9 +3,7 @@ import { Component, OnInit, OnDestroy } from "@angular/core"; import { Router } from "@angular/router"; import { Store } from "@ngrx/store"; import { map } from "rxjs/operators"; -import { - OutputDatasetObsoleteDto, -} from "@scicatproject/scicat-sdk-ts-angular"; +import { OutputDatasetObsoleteDto } from "@scicatproject/scicat-sdk-ts-angular"; import { changeRelatedDatasetsPageAction, fetchRelatedDatasetsAction, From 17936d2b704b9d74e8d1fbe6771c9268b0c88686 Mon Sep 17 00:00:00 2001 From: Abdi Mo Date: Mon, 11 May 2026 14:51:15 +0200 Subject: [PATCH 09/11] added pipe for test --- .../related-datasets/related-datasets.component.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/datasets/related-datasets/related-datasets.component.spec.ts b/src/app/datasets/related-datasets/related-datasets.component.spec.ts index 2781776487..7e79a003aa 100644 --- a/src/app/datasets/related-datasets/related-datasets.component.spec.ts +++ b/src/app/datasets/related-datasets/related-datasets.component.spec.ts @@ -29,6 +29,7 @@ import { import { provideHttpClientTesting } from "@angular/common/http/testing"; import { FileSizePipe } from "shared/pipes/filesize.pipe"; import { selectColumnsWithHasFetchedSettings } from "state-management/selectors/user.selectors"; +import { JsonHeadPipe } from "shared/pipes/json-head.pipe"; describe("RelatedDatasetsComponent", () => { let component: RelatedDatasetsComponent; @@ -52,6 +53,7 @@ describe("RelatedDatasetsComponent", () => { providers: [ DatePipe, FileSizePipe, + JsonHeadPipe, provideMockStore({ selectors: [ { From a53e166a5707c2c5bf03a4a39cbe42b1209e6565 Mon Sep 17 00:00:00 2001 From: Abdi Mo Date: Mon, 11 May 2026 15:11:06 +0200 Subject: [PATCH 10/11] sample dashboard table now covers the white space horizontally --- .../samples/sample-dashboard/sample-dashboard.component.html | 2 +- .../samples/sample-dashboard/sample-dashboard.component.scss | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/samples/sample-dashboard/sample-dashboard.component.html b/src/app/samples/sample-dashboard/sample-dashboard.component.html index ba479e0cd2..818e1f7d7c 100644 --- a/src/app/samples/sample-dashboard/sample-dashboard.component.html +++ b/src/app/samples/sample-dashboard/sample-dashboard.component.html @@ -75,7 +75,7 @@
-
+
Date: Fri, 22 May 2026 11:35:03 +0200 Subject: [PATCH 11/11] remove display:flow-root and fix root cause --- src/app/datasets/datafiles/datafiles.component.scss | 1 - .../configurable-actions/configurable-actions.component.scss | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/datasets/datafiles/datafiles.component.scss b/src/app/datasets/datafiles/datafiles.component.scss index 4603154c33..859458675a 100644 --- a/src/app/datasets/datafiles/datafiles.component.scss +++ b/src/app/datasets/datafiles/datafiles.component.scss @@ -9,7 +9,6 @@ mat-icon { .datafiles-header { margin-top: 1em; min-height: 40px; - display: flow-root; .nbr-of-files { font-size: larger; diff --git a/src/app/shared/modules/configurable-actions/configurable-actions.component.scss b/src/app/shared/modules/configurable-actions/configurable-actions.component.scss index a0d3feb528..6f42afefb1 100644 --- a/src/app/shared/modules/configurable-actions/configurable-actions.component.scss +++ b/src/app/shared/modules/configurable-actions/configurable-actions.component.scss @@ -1,4 +1,4 @@ .configurable-actions { - float: right; - //margin: 1em; + display: flex; + justify-content: flex-end; }