Skip to content

Commit d555c5a

Browse files
authored
RELEASE 01-07-2025 (#1924)
## Description Short description of the pull request ## Motivation Background on use case, changes needed ## Fixes: Please provide a list of the fixes implemented in this PR * Items added ## Changes: Please provide a list of the changes implemented by this PR * changes made ## Tests included - [ ] Included for each change/fix? - [ ] Passing? (Merge will not be approved unless this is checked) ## Documentation - [ ] swagger documentation updated \[required\] - [ ] official documentation updated \[nice-to-have\] ### official documentation info If you have updated the official documentation, please provide PR # and URL of the pages where the updates are included ## Backend version - [ ] Does it require a specific version of the backend - which version of the backend is required: ## Summary by Sourcery Unify and streamline table rendering across the application by replacing bespoke table implementations with a shared dynamic-mat-table component, introduce a fully integrated files dashboard with state management and pagination, persist user table preferences, expand datafiles action types with JSON-download support, and add configurable main-page routing along with accompanying state, effects, and tests. New Features: - Replace custom dataset, samples, files, jobs, and metadata tables with a centralized dynamic-mat-table component - Add a files dashboard for origDatablocks with pagination, sorting, and global search via new NgRx state slice, selectors, actions, and effects - Enable user-configurable table settings (columns, sort, pagination) persisted through user settings and TableConfigService - Introduce a new 'json-download' type for datafiles actions with templated payloads and filename substitution - Add MainPageConfiguration and MainPageGuard to route users to configurable default main pages Enhancements: - Refactor AppConfigService to support defaultMainPage and add validation for application configuration - Migrate job and sample handling to SciCat SDK v3 endpoints and DTOs, updating effects, selectors, and reducers - Consolidate HTML and SCSS across multiple components, removing redundant markup and styles for tables and cards - Extend MetadataViewComponent to support export rendering and paging mode configuration - Bump dependencies and generator scripts (openapi-generator-cli, scicat-sdk-ts-angular, zone.js, @types/node) and add a lint:errors task CI: - Update SDK generation scripts to openapi-generator-cli v7.13.0 - Add lint:errors npm script Documentation: - Add comprehensive Datafiles Actions documentation for form and JSON-download configurations Tests: - Revise and expand unit tests for dynamic-mat-table interactions, convertSavedColumns logic, nested metadata resolution, files selectors, and new event types
2 parents a0823b3 + 77722e6 commit d555c5a

File tree

67 files changed

+2570
-1664
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+2570
-1664
lines changed

CI/e2e/frontend.config.e2e.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"archiveWorkflowEnabled": false,
55
"datasetReduceEnabled": true,
66
"datasetJsonScientificMetadata": true,
7+
"editDatasetEnabled": true,
78
"editDatasetSampleEnabled": true,
89
"editMetadataEnabled": true,
910
"editPublishedData": false,

cypress/e2e/datasets/datasets-datafiles.cy.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ describe("Dataset datafiles", () => {
4444

4545
cy.isLoading();
4646

47-
cy.contains("mat-row", "Cypress Dataset").first().click();
47+
cy.get("mat-row").contains("Cypress Dataset").first().click();
4848

4949
cy.wait("@fetch");
5050

@@ -101,7 +101,7 @@ describe("Dataset datafiles", () => {
101101

102102
cy.isLoading();
103103

104-
cy.contains("mat-row", "Cypress Dataset").first().click();
104+
cy.get("mat-row").contains("Cypress Dataset").first().click();
105105

106106
cy.wait("@fetch");
107107

cypress/e2e/datasets/datasets-publish.cy.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe("Datasets", () => {
2323

2424
cy.isLoading();
2525

26-
cy.get("[data-cy=checkboxInput]").first().click();
26+
cy.get(".dataset-table input[type='checkbox']").first().click();
2727

2828
cy.get("#addToBatchButton").click();
2929

cypress/e2e/datasets/datasets-share.cy.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe("Datasets", () => {
2323

2424
cy.isLoading();
2525

26-
cy.get("[data-cy=checkboxInput]").first().click();
26+
cy.get(".dataset-table input[type='checkbox']").first().click();
2727

2828
cy.get("#addToBatchButton").click();
2929

package-lock.json

Lines changed: 437 additions & 436 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"watch": "ng build --watch --configuration default",
1010
"test": "ng test --watch=false --source-map=false",
1111
"lint": "ng lint",
12+
"lint:errors": "ng lint --quiet",
1213
"lint:fix": "ng lint --fix",
1314
"betterer": "betterer",
1415
"cypress:open": "cypress open",
@@ -54,7 +55,7 @@
5455
"shortid": "^2.2.16",
5556
"socket.io-client": "^4.7.2",
5657
"tslib": "^2.4.0",
57-
"zone.js": "^0.15.0"
58+
"zone.js": "^0.15.1"
5859
},
5960
"devDependencies": {
6061
"@angular-devkit/build-angular": "^19.2.9",
@@ -76,7 +77,7 @@
7677
"@types/jasmine": "^5.1.0",
7778
"@types/lodash-es": "^4.17.12",
7879
"@types/luxon": "^3.3.0",
79-
"@types/node": "^22.0.0",
80+
"@types/node": "^24.0.3",
8081
"@types/shortid": "2.2.0",
8182
"@types/source-map-support": "^0.5.3",
8283
"@typescript-eslint/eslint-plugin": "^8.32.0",

src/app/app-config.service.spec.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
import { HttpClient } from "@angular/common/http";
22
import { TestBed } from "@angular/core/testing";
3-
import { AppConfig, AppConfigService, HelpMessages } from "app-config.service";
3+
import {
4+
AppConfigInterface,
5+
AppConfigService,
6+
HelpMessages,
7+
} from "app-config.service";
48
import { of } from "rxjs";
59
import { MockHttp } from "shared/MockStubs";
610

7-
const appConfig: AppConfig = {
11+
const appConfig: AppConfigInterface = {
12+
defaultMainPage: {
13+
nonAuthenticatedUser: "DATASETS",
14+
authenticatedUser: "DATASETS",
15+
},
816
skipSciCatLoginPageEnabled: false,
917
accessTokenPrefix: "",
1018
addDatasetEnabled: true,
1119
archiveWorkflowEnabled: true,
1220
datasetReduceEnabled: true,
1321
datasetJsonScientificMetadata: true,
22+
editDatasetEnabled: true,
1423
editDatasetSampleEnabled: true,
1524
editMetadataEnabled: true,
1625
editPublishedData: true,

src/app/app-config.service.ts

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,19 @@ export class HelpMessages {
3535
}
3636
}
3737

38-
export interface AppConfig {
38+
export enum MainPageOptions {
39+
DATASETS = "/datasets",
40+
PROPOSALS = "/proposals",
41+
INSTRUMENTS = "/instruments",
42+
SAMPLES = "/samples",
43+
}
44+
45+
export class MainPageConfiguration {
46+
nonAuthenticatedUser: keyof typeof MainPageOptions;
47+
authenticatedUser: keyof typeof MainPageOptions;
48+
}
49+
50+
export interface AppConfigInterface {
3951
skipSciCatLoginPageEnabled?: boolean;
4052
accessTokenPrefix: string;
4153
addDatasetEnabled: boolean;
@@ -45,6 +57,7 @@ export interface AppConfig {
4557
datasetDetailsShowMissingProposalId: boolean;
4658
datafilesActionsEnabled: boolean;
4759
datafilesActions: any[];
60+
editDatasetEnabled: boolean;
4861
editDatasetSampleEnabled: boolean;
4962
editMetadataEnabled: boolean;
5063
editPublishedData: boolean;
@@ -106,9 +119,22 @@ export interface AppConfig {
106119
datasetDetailComponent?: DatasetDetailComponentConfig;
107120
labelsLocalization?: LabelsLocalization;
108121
dateFormat?: string;
122+
defaultMainPage?: MainPageConfiguration;
109123
}
110124

111-
@Injectable()
125+
function isMainPageConfiguration(obj: any): obj is MainPageConfiguration {
126+
const validKeys = Object.keys(MainPageOptions);
127+
return (
128+
obj &&
129+
typeof obj === "object" &&
130+
validKeys.includes(obj.nonAuthenticatedUser) &&
131+
validKeys.includes(obj.authenticatedUser)
132+
);
133+
}
134+
135+
@Injectable({
136+
providedIn: "root",
137+
})
112138
export class AppConfigService {
113139
private appConfig: object = {};
114140

@@ -130,13 +156,37 @@ export class AppConfigService {
130156
console.error("No config provided.");
131157
}
132158
}
159+
160+
const config: AppConfigInterface = this.appConfig as AppConfigInterface;
161+
if (
162+
"defaultMainPage" in config &&
163+
isMainPageConfiguration(config.defaultMainPage)
164+
) {
165+
config.defaultMainPage.nonAuthenticatedUser = Object.keys(
166+
MainPageOptions,
167+
).includes(config.defaultMainPage.nonAuthenticatedUser)
168+
? config.defaultMainPage.nonAuthenticatedUser
169+
: "DATASETS";
170+
config.defaultMainPage.authenticatedUser = Object.keys(
171+
MainPageOptions,
172+
).includes(config.defaultMainPage.authenticatedUser)
173+
? config.defaultMainPage.authenticatedUser
174+
: "DATASETS";
175+
} else {
176+
config.defaultMainPage = {
177+
nonAuthenticatedUser: "DATASETS",
178+
authenticatedUser: "DATASETS",
179+
} as MainPageConfiguration;
180+
}
181+
182+
this.appConfig = config;
133183
}
134184

135-
getConfig(): AppConfig {
185+
getConfig(): AppConfigInterface {
136186
if (!this.appConfig) {
137187
console.error("AppConfigService: Configuration not loaded!");
138188
}
139189

140-
return this.appConfig as AppConfig;
190+
return this.appConfig as AppConfigInterface;
141191
}
142192
}

src/app/app-routing/app-routing.module.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { ErrorPageComponent } from "shared/modules/error-page/error-page.compone
55
import { AppLayoutComponent } from "_layout/app-layout/app-layout.component";
66
import { AppMainLayoutComponent } from "_layout/app-main-layout/app-main-layout.component";
77
import { ServiceGuard } from "./service.guard";
8+
import { MainPageGuard } from "./main-page";
9+
import { RedirectingComponent } from "./redirecting.component";
810

911
export const routes: Routes = [
1012
{
@@ -13,7 +15,8 @@ export const routes: Routes = [
1315
children: [
1416
{
1517
path: "",
16-
redirectTo: "/datasets",
18+
canActivate: [MainPageGuard],
19+
component: RedirectingComponent,
1720
pathMatch: "full",
1821
},
1922
{

src/app/app-routing/main-page.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Injectable } from "@angular/core";
2+
import { CanActivate, Router } from "@angular/router";
3+
import {
4+
AppConfigService,
5+
MainPageConfiguration,
6+
MainPageOptions,
7+
} from "app-config.service";
8+
import { AuthService } from "shared/services/auth/auth.service";
9+
10+
@Injectable({ providedIn: "root" })
11+
export class MainPageGuard implements CanActivate {
12+
constructor(
13+
private router: Router,
14+
private appConfigService: AppConfigService,
15+
private authService: AuthService,
16+
) {}
17+
18+
canActivate(): boolean {
19+
const defaultMainPage: MainPageConfiguration =
20+
this.appConfigService.getConfig().defaultMainPage;
21+
22+
const userLoggedIn = this.authService.isAuthenticated();
23+
24+
this.router.navigate([
25+
MainPageOptions[
26+
userLoggedIn
27+
? defaultMainPage.authenticatedUser
28+
: defaultMainPage.nonAuthenticatedUser
29+
],
30+
]);
31+
return false;
32+
}
33+
}

0 commit comments

Comments
 (0)