diff --git a/frontend/src/app/pages/data-models-page/visualization/visualization.component.ts b/frontend/src/app/pages/data-models-page/visualization/visualization.component.ts
index 7f78f3e..7fe39dc 100644
--- a/frontend/src/app/pages/data-models-page/visualization/visualization.component.ts
+++ b/frontend/src/app/pages/data-models-page/visualization/visualization.component.ts
@@ -10,7 +10,7 @@ import {
import { createTidyTree } from './tidy-tree';
import { FormsModule } from '@angular/forms';
import { ErrorService } from '../services/error.service';
-import { NgForOf, NgIf, NgClass } from '@angular/common';
+import { NgClass } from '@angular/common';
import { BreadcrumbComponent } from './breadcrumb/breadcrumb.component';
import { SearchBarComponent } from './search-bar/search-bar.component';
@@ -19,7 +19,7 @@ import { SearchBarComponent } from './search-bar/search-bar.component';
templateUrl: './visualization.component.html',
styleUrls: ['./visualization.component.css'],
standalone: true,
- imports: [NgForOf, NgIf, NgClass, FormsModule, BreadcrumbComponent, SearchBarComponent],
+ imports: [NgClass, FormsModule, BreadcrumbComponent, SearchBarComponent],
})
export class VisualizationComponent implements OnInit, OnChanges {
@Input() dataModelHierarchy: any;
diff --git a/frontend/src/app/pages/federations-page/federations-page.component.ts b/frontend/src/app/pages/federations-page/federations-page.component.ts
index 17ccde9..43f7859 100644
--- a/frontend/src/app/pages/federations-page/federations-page.component.ts
+++ b/frontend/src/app/pages/federations-page/federations-page.component.ts
@@ -4,7 +4,6 @@ import { FederationService } from '../../services/federation.service';
import { AuthService } from '../../services/auth.service';
import { Federation } from '../../interfaces/federations.interface';
import { filter, Subject, takeUntil } from 'rxjs';
-import { FilterComponent } from "./filter/filter.component";
import { FederationCardComponent } from "./federation-card/federation-card.component";
import { AddFederationCardComponent } from "./add-federation-card/add-federation-card.component";
import {MatDialog} from "@angular/material/dialog";
@@ -15,12 +14,10 @@ import {ConfirmationDialogComponent} from "./confirmation-dialog/confirmation-di
templateUrl: './federations-page.component.html',
styleUrls: ['./federations-page.component.css'],
imports: [
- FilterComponent,
RouterOutlet,
FederationCardComponent,
AddFederationCardComponent,
],
- standalone: true
})
export class FederationsPageComponent implements OnInit, OnDestroy {
selectedFilter = 'All';
diff --git a/frontend/src/app/pages/landing-page/landing-page.component.html b/frontend/src/app/pages/landing-page/landing-page.component.html
index 0d13b0e..71e937d 100644
--- a/frontend/src/app/pages/landing-page/landing-page.component.html
+++ b/frontend/src/app/pages/landing-page/landing-page.component.html
@@ -4,32 +4,35 @@
-
-
![]()
-
-
{{ federation.title }}
-
-
- Institutions: {{ federation.institutions }} |
-
- Data Records: {{ federation.records | number }}
-
+ @for (federation of federations; track federation) {
+
+
![]()
+
+
{{ federation.title }}
+
+ @if (federation.institutions != '0') {
+
+ Institutions: {{ federation.institutions }} |
+
+ }
+ Data Records: {{ federation.records | number }}
+
+
-
+ }
- Welcome to the
Medical Informatics Platform
+ Welcome to the
Medical Informatics Platform
@@ -76,11 +79,13 @@
Algorithms
-
+ @if (!isLoggedIn()) {
+
+ }
diff --git a/frontend/src/app/pages/shared/footer/footer.component.ts b/frontend/src/app/pages/shared/footer/footer.component.ts
index b4ae9de..cec209e 100644
--- a/frontend/src/app/pages/shared/footer/footer.component.ts
+++ b/frontend/src/app/pages/shared/footer/footer.component.ts
@@ -1,10 +1,10 @@
-import { CommonModule } from '@angular/common';
+
import { Component } from '@angular/core';
@Component({
selector: 'app-footer',
standalone: true,
- imports: [CommonModule],
+ imports: [],
templateUrl: './footer.component.html',
styleUrl: './footer.component.css'
})
diff --git a/frontend/src/app/pages/shared/header/header.component.spec.ts b/frontend/src/app/pages/shared/header/header.component.spec.ts
index 204ed6e..b75ef49 100644
--- a/frontend/src/app/pages/shared/header/header.component.spec.ts
+++ b/frontend/src/app/pages/shared/header/header.component.spec.ts
@@ -1,6 +1,8 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { provideRouter } from '@angular/router';
import { HeaderComponent } from './header.component';
+import { AuthService } from '../../../services/auth.service';
describe('HeaderComponent', () => {
let component: HeaderComponent;
@@ -8,7 +10,18 @@ describe('HeaderComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
- imports: [HeaderComponent]
+ imports: [HeaderComponent],
+ providers: [
+ provideRouter([]),
+ {
+ provide: AuthService,
+ useValue: {
+ isLoggedIn: () => false,
+ login: jasmine.createSpy('login'),
+ logout: jasmine.createSpy('logout'),
+ },
+ },
+ ],
})
.compileComponents();
diff --git a/frontend/src/app/pages/shared/header/header.component.ts b/frontend/src/app/pages/shared/header/header.component.ts
index ba41c83..2f917aa 100644
--- a/frontend/src/app/pages/shared/header/header.component.ts
+++ b/frontend/src/app/pages/shared/header/header.component.ts
@@ -1,4 +1,4 @@
-import { CommonModule } from '@angular/common';
+
import { NavbarComponent } from '../navbar/navbar.component';
import {NavigationEnd, Router, RouterModule} from '@angular/router';
import { AuthService } from '../../../services/auth.service';
@@ -8,7 +8,7 @@ import {filter} from "rxjs";
@Component({
selector: 'app-header',
standalone: true,
- imports: [CommonModule, NavbarComponent, RouterModule],
+ imports: [NavbarComponent, RouterModule],
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
diff --git a/frontend/src/app/pages/shared/navbar/navbar.component.ts b/frontend/src/app/pages/shared/navbar/navbar.component.ts
index dd5689e..46cc037 100644
--- a/frontend/src/app/pages/shared/navbar/navbar.component.ts
+++ b/frontend/src/app/pages/shared/navbar/navbar.component.ts
@@ -1,11 +1,11 @@
-import { CommonModule, NgIf } from '@angular/common';
+
import { Component } from '@angular/core';
import { RouterModule } from '@angular/router';
@Component({
selector: 'app-navbar',
standalone: true,
- imports: [CommonModule, RouterModule, NgIf],
+ imports: [RouterModule],
templateUrl: './navbar.component.html',
styleUrl: './navbar.component.css'
})
diff --git a/frontend/src/main.ts b/frontend/src/main.ts
index fd306f5..b240b0c 100644
--- a/frontend/src/main.ts
+++ b/frontend/src/main.ts
@@ -1,3 +1,4 @@
+import { provideZoneChangeDetection } from "@angular/core";
import 'zone.js'; // Required for Angular
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
@@ -7,7 +8,7 @@ import {appRoutes} from "./app/app.routes";
bootstrapApplication(AppComponent, {
providers: [
- provideRouter(appRoutes),
+ provideZoneChangeDetection(),provideRouter(appRoutes),
provideHttpClient()
]
}).catch(err => console.error(err));
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
index ab1f217..dda3d01 100644
--- a/frontend/tsconfig.json
+++ b/frontend/tsconfig.json
@@ -19,11 +19,7 @@
"moduleResolution": "bundler",
"importHelpers": true,
"target": "ES2022",
- "module": "ES2022",
- "lib": [
- "ES2022",
- "dom"
- ]
+ "module": "ES2022"
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
diff --git a/kubernetes/README.md b/kubernetes/README.md
index a4c3f97..d5d6f9f 100644
--- a/kubernetes/README.md
+++ b/kubernetes/README.md
@@ -1,59 +1,65 @@
# Kubernetes Deployment Guide
-This guide explains how to deploy the **Datacatalog** using **MicroK8s** and **Helm**.
-
----
+This chart deploys the frontend, backend, data quality tool, and PostgreSQL for DataCatalog.
## Prerequisites
-1. **MicroK8s**: A lightweight Kubernetes distribution.
-2. **Helm**: A package manager for Kubernetes (already included in MicroK8s).
-
----
-
-## Deployment Steps
-
-### 1. Install MicroK8s
+- Kubernetes cluster
+- Helm 3
+- A namespace where the release will run
-To install MicroK8s, run the following command:
+For local MicroK8s usage:
```bash
sudo snap install microk8s --classic
+microk8s enable dns ingress helm3
```
-### 2. Enable Required MicroK8s Add-ons
+## Required Configuration
-Enable the necessary MicroK8s add-ons for DNS, ingress, and Helm:
+Update `values.yaml` before deploying:
-```bash
-microk8s enable dns ingress helm3
-```
+- `managed_cluster`: `false` for local NodePort access, `true` for ingress-based clusters
+- `namespace`: target namespace
+- `datacatalog_images.repository` and `datacatalog_images.tag`: image location and release tag
+- `datacatalogDb.image`: PostgreSQL image, currently `postgres:18.3`
+- `backend.publicHost`: public hostname used by the frontend and auth callback
+- `backend.dqtUrl`: URL of the data quality tool service
-### 3. Configure the `values.yaml` File
+The chart expects a secret named `datacatalog-secrets` with:
-Before deploying the **Datacatalog**, update the `values.yaml` file with your Keycloak configuration details for authentication. Here’s an example:
+- `db.user`
+- `db.password`
+- `keycloak.client-id`
+- `keycloak.client-secret`
-```yaml
-backend:
- authentication: "true"
- keycloak:
- authUrl: "https://keycloak.example.com"
- realm: "your-realm"
- clientId: "your-client-id"
- clientSecret: "your-client-secret"
+Example:
+
+```bash
+kubectl -n default create secret generic datacatalog-secrets \
+ --from-literal=db.user=postgres \
+ --from-literal=db.password=test \
+ --from-literal=keycloak.client-id=datacatalog \
+ --from-literal=keycloak.client-secret=change-me
```
-- Replace `https://keycloak.example.com` with your Keycloak server URL.
-- Replace `your-realm`, `your-client-id`, and `your-client-secret` with your actual Keycloak configuration.
+## Install Or Upgrade
-### 4. Deploy the Application
+From the `kubernetes/` directory:
-Navigate to the directory containing your Helm chart and deploy the **Datacatalog** using:
+```bash
+helm upgrade --install datacatalog . -n default --create-namespace
+```
+
+With MicroK8s:
```bash
-microk8s helm3 install datacatalog .
+microk8s helm3 upgrade --install datacatalog . -n default --create-namespace
```
-Here:
-- `datacatalog` is the release name for your deployment.
-- `.` refers to the current directory containing the Helm chart.
\ No newline at end of file
+## Access Model
+
+- `managed_cluster: false`: frontend and backend are exposed through NodePorts defined in the templates
+- `managed_cluster: true`: the chart creates an ingress for the frontend host in `backend.publicHost`
+
+The database uses a PVC and mounts storage at `/var/lib/postgresql`.
diff --git a/kubernetes/templates/database.yaml b/kubernetes/templates/database.yaml
index dc74789..be44f1f 100644
--- a/kubernetes/templates/database.yaml
+++ b/kubernetes/templates/database.yaml
@@ -56,7 +56,7 @@ spec:
- name: POSTGRES_DB
value: {{ .Values.datacatalogDb.db | quote }}
volumeMounts:
- - mountPath: /var/lib/postgresql/data
+ - mountPath: /var/lib/postgresql
name: postgres-data
volumes:
- name: postgres-data
diff --git a/kubernetes/values.yaml b/kubernetes/values.yaml
index 8549290..047296c 100644
--- a/kubernetes/values.yaml
+++ b/kubernetes/values.yaml
@@ -22,7 +22,7 @@ dqt:
flaskDebug: "1"
datacatalogDb:
- image: postgres:15
+ image: postgres:18.3
db: "datacatalog"
storage: 5Gi
@@ -38,4 +38,4 @@ backend:
persistence:
enabled: true
- accessModes: ["ReadWriteOnce"]
\ No newline at end of file
+ accessModes: ["ReadWriteOnce"]