Date: Mon, 9 Sep 2024 13:07:02 +0000
Subject: [PATCH 004/242] Remove unused file path input field in ingestor
component
---
src/app/ingestor/ingestor/ingestor.component.html | 5 -----
1 file changed, 5 deletions(-)
diff --git a/src/app/ingestor/ingestor/ingestor.component.html b/src/app/ingestor/ingestor/ingestor.component.html
index 61ab5ab39..3d19f732d 100644
--- a/src/app/ingestor/ingestor/ingestor.component.html
+++ b/src/app/ingestor/ingestor/ingestor.component.html
@@ -48,11 +48,6 @@
-
-
-
-
-
@@ -69,7 +82,23 @@
-
{{returnValue}}
+
{{returnValue}}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/ingestor/ingestor/ingestor.component.scss b/src/app/ingestor/ingestor/ingestor.component.scss
index b85eb9646..96cdeec1b 100644
--- a/src/app/ingestor/ingestor/ingestor.component.scss
+++ b/src/app/ingestor/ingestor/ingestor.component.scss
@@ -2,4 +2,15 @@
display: flex;
flex-direction: column;
gap: 1em;
+}
+
+/* src/app/ingestor/ingestor.component.scss */
+.ingestor-mixed-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.ingestor-close-button {
+ margin-left: auto;
}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/ingestor.component.ts b/src/app/ingestor/ingestor/ingestor.component.ts
index e2931bc54..82213f95c 100644
--- a/src/app/ingestor/ingestor/ingestor.component.ts
+++ b/src/app/ingestor/ingestor/ingestor.component.ts
@@ -3,6 +3,7 @@ import { AppConfigService, HelpMessages } from "app-config.service";
import { HttpClient } from '@angular/common/http';
import { IngestorMetadataEditorComponent } from '../ingestor-metadata-editor/ingestor-metadata-editor.component';
import { ActivatedRoute, Router } from '@angular/router';
+import { INGESTOR_API_ENDPOINTS_V1 } from "./ingestor-api-endpoints";
@Component({
selector: "ingestor",
@@ -19,12 +20,17 @@ export class IngestorComponent implements OnInit {
gettingStarted: string | null = null;
shoppingCartEnabled = false;
helpMessages: HelpMessages;
+
filePath: string = '';
loading: boolean = false;
forwardFacilityBackend: string = '';
+
connectedFacilityBackend: string = '';
+ connectedFacilityBackendVersion: string = '';
connectingToFacilityBackend: boolean = false;
lastUsedFacilityBackends: string[] = [];
+
+ errorMessage: string = '';
returnValue: string = '';
constructor(public appConfigService: AppConfigService, private http: HttpClient, private route: ActivatedRoute, private router: Router) { }
@@ -58,7 +64,7 @@ export class IngestorComponent implements OnInit {
facilityBackendUrlCleaned += '/';
}
- let facilityBackendUrlVersion = facilityBackendUrlCleaned + 'Version';
+ let facilityBackendUrlVersion = facilityBackendUrlCleaned + INGESTOR_API_ENDPOINTS_V1.OTHER.VERSION;
// Try to connect to the facility backend/version to check if it is available
console.log('Connecting to facility backend: ' + facilityBackendUrlVersion);
@@ -68,9 +74,11 @@ export class IngestorComponent implements OnInit {
// If the connection is successful, store the connected facility backend URL
this.connectedFacilityBackend = facilityBackendUrlCleaned;
this.connectingToFacilityBackend = false;
+ this.connectedFacilityBackendVersion = response['version'];
},
error => {
- console.error('Failed to connect to facility backend', error);
+ this.errorMessage += `${new Date().toLocaleString()}: ${error.message}
`;
+ console.error('Request failed', error);
this.connectedFacilityBackend = '';
this.connectingToFacilityBackend = false;
this.lastUsedFacilityBackends = this.loadLastUsedFacilityBackends();
@@ -90,13 +98,14 @@ export class IngestorComponent implements OnInit {
console.log('Uploading', payload);
- this.http.post(this.connectedFacilityBackend + 'Dataset/Ingest', payload).subscribe(
+ this.http.post(this.connectedFacilityBackend + INGESTOR_API_ENDPOINTS_V1.DATASET, payload).subscribe(
response => {
console.log('Upload successful', response);
this.returnValue = JSON.stringify(response);
this.loading = false;
},
error => {
+ this.errorMessage += `${new Date().toLocaleString()}: ${error.message}]
`;
console.error('Upload failed', error);
this.loading = false;
}
@@ -105,6 +114,14 @@ export class IngestorComponent implements OnInit {
forwardToIngestorPage() {
if (this.forwardFacilityBackend) {
+ this.connectingToFacilityBackend = true;
+
+ // If current route is equal to the forward route, the router will not navigate to the new route
+ if (this.connectedFacilityBackend === this.forwardFacilityBackend) {
+ this.connectToFacilityBackend(this.forwardFacilityBackend);
+ return;
+ }
+
this.router.navigate(['/ingestor'], { queryParams: { backendUrl: this.forwardFacilityBackend } });
}
}
@@ -123,10 +140,14 @@ export class IngestorComponent implements OnInit {
loadLastUsedFacilityBackends(): string[] {
// Load the list from the local Storage
- const lastUsedFacilityBackends = '["http://localhost:8000"]';
+ const lastUsedFacilityBackends = '["http://localhost:8000", "http://localhost:8888"]';
if (lastUsedFacilityBackends) {
return JSON.parse(lastUsedFacilityBackends);
}
return [];
}
+
+ clearErrorMessage(): void {
+ this.errorMessage = '';
+ }
}
\ No newline at end of file
From 80d60bdaa27f0d4edc27d672070543991ef03342 Mon Sep 17 00:00:00 2001
From: David Wiessner
Date: Thu, 12 Sep 2024 15:19:05 +0000
Subject: [PATCH 006/242] Change back to localhost:3000 instead of
backend.localhost
---
.github/workflows/test.yml | 2 +-
CI/ESS/e2e/config.e2e.json | 2 +-
CI/ESS/e2e/cypress.config.ts | 2 +-
cypress.config.ts | 2 +-
scripts/local.proxy.config.json | 2 +-
scripts/sample_data.sh | 8 ++++----
src/app/app-config.service.spec.ts | 2 +-
src/app/shared/sdk/lb.config.ts | 2 +-
src/assets/config.json | 2 +-
9 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ccd2e6df4..223e5bca8 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -124,7 +124,7 @@ jobs:
- name: Wait for Backend
run: |
npm install -g wait-on
- wait-on http://backend.localhost/api/v3/health --timeout 200000
+ wait-on http://localhost:3000/api/v3/health --timeout 200000
- name: Run Cypress tests
uses: cypress-io/github-action@v6
diff --git a/CI/ESS/e2e/config.e2e.json b/CI/ESS/e2e/config.e2e.json
index a5d14bc91..5ff1f6c9d 100644
--- a/CI/ESS/e2e/config.e2e.json
+++ b/CI/ESS/e2e/config.e2e.json
@@ -25,7 +25,7 @@
"jsonMetadataEnabled": true,
"jupyterHubUrl": "https://jupyterhub.esss.lu.se/",
"landingPage": "doi.ess.eu/detail/",
- "lbBaseURL": "http://backend.localhost",
+ "lbBaseURL": "http://localhost:3000",
"localColumns": [
{
"name": "select",
diff --git a/CI/ESS/e2e/cypress.config.ts b/CI/ESS/e2e/cypress.config.ts
index 7b8210795..3d875e105 100644
--- a/CI/ESS/e2e/cypress.config.ts
+++ b/CI/ESS/e2e/cypress.config.ts
@@ -3,7 +3,7 @@ import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
baseUrl: "http://localhost:4200",
- lbBaseUrl: "http://backend.localhost/api/v3",
+ lbBaseUrl: "http://localhost:3000/api/v3",
lbLoginEndpoint: "/Users/login?include=user",
lbTokenPrefix: "Bearer ",
viewportWidth: 1280,
diff --git a/cypress.config.ts b/cypress.config.ts
index 59f2aaafc..e19f1c8b9 100644
--- a/cypress.config.ts
+++ b/cypress.config.ts
@@ -3,7 +3,7 @@ import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
baseUrl: "http://127.0.0.1:4200",
- lbBaseUrl: "http://backend.localhost/api/v3",
+ lbBaseUrl: "http://localhost:3000/api/v3",
lbLoginEndpoint: "/Users/login",
lbTokenPrefix: "Bearer ",
viewportWidth: 1280,
diff --git a/scripts/local.proxy.config.json b/scripts/local.proxy.config.json
index c447e2055..ca6147ce5 100644
--- a/scripts/local.proxy.config.json
+++ b/scripts/local.proxy.config.json
@@ -1,6 +1,6 @@
{
"/api/v3/*": {
- "target": "http://backend.localhost",
+ "target": "http://localhost:3000",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
diff --git a/scripts/sample_data.sh b/scripts/sample_data.sh
index 727782e5b..692833eb3 100755
--- a/scripts/sample_data.sh
+++ b/scripts/sample_data.sh
@@ -1,11 +1,11 @@
#!/bin/sh
# UPDATE ACCESS TOKEN
-http POST http://backend.localhost/api/v3/RawDatasets?access_token=wDBhvBhKAc0OL8Hrc0WP3CcuIFSUVjEFyxF38sNHTUgHZaunDlxqxBeDOSVVJaJx < raw_dataset.json
+http POST http://localhost:3000/api/v3/RawDatasets?access_token=wDBhvBhKAc0OL8Hrc0WP3CcuIFSUVjEFyxF38sNHTUgHZaunDlxqxBeDOSVVJaJx < raw_dataset.json
-http POST http://backend.localhost/api/v3/Datablocks?access_token=S5GtalRhAs1jT0PJovPmv8A3QbLwoHeUoRgh3VKiqFcchULvO3zU4VYjSko589fN < datablock_two.json
+http POST http://localhost:3000/api/v3/Datablocks?access_token=S5GtalRhAs1jT0PJovPmv8A3QbLwoHeUoRgh3VKiqFcchULvO3zU4VYjSko589fN < datablock_two.json
-# curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d raw_dataset.json 'http://backend.localhost/api/v3/RawDatasets?access_token=QNV0Su9omZy9R6I38H7iv0aMbbWW0j7LsGvve2YoWJvif4MwyLGSSkdZ8RWsIDVq'
+# curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d raw_dataset.json 'http://localhost:3000/api/v3/RawDatasets?access_token=QNV0Su9omZy9R6I38H7iv0aMbbWW0j7LsGvve2YoWJvif4MwyLGSSkdZ8RWsIDVq'
-# curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d datablock.json 'http://backend.localhost/api/v3/Datablocks?access_token=QNV0Su9omZy9R6I38H7iv0aMbbWW0j7LsGvve2YoWJvif4MwyLGSSkdZ8RWsIDVq'
+# curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d datablock.json 'http://localhost:3000/api/v3/Datablocks?access_token=QNV0Su9omZy9R6I38H7iv0aMbbWW0j7LsGvve2YoWJvif4MwyLGSSkdZ8RWsIDVq'
diff --git a/src/app/app-config.service.spec.ts b/src/app/app-config.service.spec.ts
index e3310ebca..a043999e8 100644
--- a/src/app/app-config.service.spec.ts
+++ b/src/app/app-config.service.spec.ts
@@ -34,7 +34,7 @@ const appConfig: AppConfig = {
jsonMetadataEnabled: true,
jupyterHubUrl: "https://jupyterhub.esss.lu.se/",
landingPage: "doi2.psi.ch/detail/",
- lbBaseURL: "http://backend.localhost",
+ lbBaseURL: "http://localhost:3000",
localColumns: [
{
name: "select",
diff --git a/src/app/shared/sdk/lb.config.ts b/src/app/shared/sdk/lb.config.ts
index 398216a63..9f8cf2b64 100644
--- a/src/app/shared/sdk/lb.config.ts
+++ b/src/app/shared/sdk/lb.config.ts
@@ -14,7 +14,7 @@
*
* export class MyApp {
* constructor() {
- * LoopBackConfig.setBaseURL('http://backend.localhost');
+ * LoopBackConfig.setBaseURL('http://localhost:3000');
* LoopBackConfig.setApiVersion('api');
* }
* }
diff --git a/src/assets/config.json b/src/assets/config.json
index d2a42303f..c41fd6c04 100644
--- a/src/assets/config.json
+++ b/src/assets/config.json
@@ -25,7 +25,7 @@
"jsonMetadataEnabled": true,
"jupyterHubUrl": "https://jupyterhub.esss.lu.se/",
"landingPage": "doi.ess.eu/detail/",
- "lbBaseURL": "http://backend.localhost",
+ "lbBaseURL": "http://localhost:3000",
"localColumns": [
{
"name": "select",
From 27a65441c80270c95ef61abc827be8a72677d48e Mon Sep 17 00:00:00 2001
From: David Wiessner
Date: Thu, 12 Sep 2024 15:34:59 +0000
Subject: [PATCH 007/242] Change back the files to original state
---
.vscode/settings.json | 16 ++++++++++++++++
src/app/app-config.service.spec.ts | 2 +-
src/assets/config.json | 2 +-
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/.vscode/settings.json b/.vscode/settings.json
index f5f9be20e..3bd83d36a 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,4 +1,20 @@
{
+ "workbench.colorCustomizations": {
+ "activityBar.background": "#0e3041",
+ "activityBar.foreground": "#e7e7e7",
+ "activityBar.inactiveForeground": "#e7e7e799",
+ "activityBarBadge.background": "#b82888",
+ "activityBarBadge.foreground": "#e7e7e7",
+ "titleBar.activeBackground": "#051117",
+ "titleBar.inactiveBackground": "#05111799",
+ "titleBar.activeForeground": "#e7e7e7",
+ "titleBar.inactiveForeground": "#e7e7e799",
+ "statusBar.background": "#051117",
+ "statusBarItem.hoverBackground": "#0e3041",
+ "statusBar.foreground": "#e7e7e7",
+ "activityBar.activeBackground": "#0e3041",
+ "activityBar.activeBorder": "#b82888"
+ },
"peacock.color": "#051117",
"editor.tabSize": 2,
"diffEditor.wordWrap": "on",
diff --git a/src/app/app-config.service.spec.ts b/src/app/app-config.service.spec.ts
index a043999e8..4538eea22 100644
--- a/src/app/app-config.service.spec.ts
+++ b/src/app/app-config.service.spec.ts
@@ -34,7 +34,7 @@ const appConfig: AppConfig = {
jsonMetadataEnabled: true,
jupyterHubUrl: "https://jupyterhub.esss.lu.se/",
landingPage: "doi2.psi.ch/detail/",
- lbBaseURL: "http://localhost:3000",
+ lbBaseURL: "http://127.0.0.1:3000",
localColumns: [
{
name: "select",
diff --git a/src/assets/config.json b/src/assets/config.json
index c41fd6c04..759ea9507 100644
--- a/src/assets/config.json
+++ b/src/assets/config.json
@@ -25,7 +25,7 @@
"jsonMetadataEnabled": true,
"jupyterHubUrl": "https://jupyterhub.esss.lu.se/",
"landingPage": "doi.ess.eu/detail/",
- "lbBaseURL": "http://localhost:3000",
+ "lbBaseURL": "http://127.0.0.1:3000",
"localColumns": [
{
"name": "select",
From 03738a9bbf1759b3f19a2983e2b08cb36ad0d8d0 Mon Sep 17 00:00:00 2001
From: David Wiessner
Date: Wed, 18 Sep 2024 15:25:39 +0000
Subject: [PATCH 008/242] fix ingestor endpoint
---
src/app/ingestor/ingestor/ingestor-api-endpoints.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/app/ingestor/ingestor/ingestor-api-endpoints.ts b/src/app/ingestor/ingestor/ingestor-api-endpoints.ts
index 12e3624f5..aa0ee1e75 100644
--- a/src/app/ingestor/ingestor/ingestor-api-endpoints.ts
+++ b/src/app/ingestor/ingestor/ingestor-api-endpoints.ts
@@ -1,5 +1,5 @@
export const INGESTOR_API_ENDPOINTS_V1 = {
- DATASET: "datasets",
+ DATASET: "dataset",
TRANSFER: "transfer",
OTHER: {
VERSION: 'version',
From ff6bed97dffc66b31cc0dc881107c2b22cf8f2c1 Mon Sep 17 00:00:00 2001
From: David Wiessner
Date: Wed, 18 Sep 2024 15:34:24 +0000
Subject: [PATCH 009/242] fix sonarcube issues
---
src/app/ingestor/ingestor/ingestor.component.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/app/ingestor/ingestor/ingestor.component.ts b/src/app/ingestor/ingestor/ingestor.component.ts
index 82213f95c..99cf89e0f 100644
--- a/src/app/ingestor/ingestor/ingestor.component.ts
+++ b/src/app/ingestor/ingestor/ingestor.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit, SimpleChanges, ViewChild } from "@angular/core";
+import { Component, OnInit, ViewChild } from "@angular/core";
import { AppConfigService, HelpMessages } from "app-config.service";
import { HttpClient } from '@angular/common/http';
import { IngestorMetadataEditorComponent } from '../ingestor-metadata-editor/ingestor-metadata-editor.component';
@@ -60,7 +60,7 @@ export class IngestorComponent implements OnInit {
connectToFacilityBackend(facilityBackendUrl: string): boolean {
let facilityBackendUrlCleaned = facilityBackendUrl.slice();
// Check if last symbol is a slash and add version endpoint
- if (facilityBackendUrlCleaned.slice(-1) !== '/') {
+ if (!facilityBackendUrlCleaned.endsWith('/')) {
facilityBackendUrlCleaned += '/';
}
From dd61bdde3fcedf803267eda5594de288df40e786 Mon Sep 17 00:00:00 2001
From: David Wiessner
Date: Thu, 3 Oct 2024 13:14:03 +0000
Subject: [PATCH 010/242] Prepare showing the transfer list
---
.../ingestor-metadata-editor.component.ts | 15 +--
src/app/ingestor/ingestor.module.ts | 6 +-
.../ingestor/ingestor/ingestor.component.html | 92 +++++++++++++++----
.../ingestor/ingestor/ingestor.component.ts | 57 +++++++++++-
4 files changed, 139 insertions(+), 31 deletions(-)
diff --git a/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor.component.ts b/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor.component.ts
index 19b7d76c4..d9cd5b12b 100644
--- a/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor.component.ts
+++ b/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor.component.ts
@@ -8,11 +8,14 @@ import { Component, EventEmitter, Output } from '@angular/core';
export class IngestorMetadataEditorComponent {
metadata: string = '';
- // Optional: EventEmitter, um Änderungen an der Metadata zu melden
- @Output() metadataChange = new EventEmitter();
+ clearMetadata() {
+ this.metadata = '';
+ }
+ // Optional: EventEmitter, um Änderungen an der Metadata zu melden
+ @Output() metadataChange = new EventEmitter();
- onMetadataChange(newMetadata: string) {
- this.metadata = newMetadata;
- this.metadataChange.emit(this.metadata);
- }
+ onMetadataChange(newMetadata: string) {
+ this.metadata = newMetadata;
+ this.metadataChange.emit(this.metadata);
+ }
}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor.module.ts b/src/app/ingestor/ingestor.module.ts
index bd0400815..febb5625c 100644
--- a/src/app/ingestor/ingestor.module.ts
+++ b/src/app/ingestor/ingestor.module.ts
@@ -11,6 +11,8 @@ import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
import { FormsModule } from "@angular/forms";
import { MatListModule } from '@angular/material/list';
import { MatIconModule } from '@angular/material/icon';
+import { MatTabsModule } from "@angular/material/tabs";
+import { MatTableModule } from "@angular/material/table";
@NgModule({
declarations: [
@@ -27,7 +29,9 @@ import { MatIconModule } from '@angular/material/icon';
MatProgressSpinnerModule,
RouterModule,
MatListModule,
- MatIconModule
+ MatIconModule,
+ MatTabsModule,
+ MatTableModule,
],
})
export class IngestorModule { }
diff --git a/src/app/ingestor/ingestor/ingestor.component.html b/src/app/ingestor/ingestor/ingestor.component.html
index a61b5ca5b..b458d1edd 100644
--- a/src/app/ingestor/ingestor/ingestor.component.html
+++ b/src/app/ingestor/ingestor/ingestor.component.html
@@ -1,7 +1,7 @@
- Ingestor-Connection
+ Control center
@@ -30,29 +30,80 @@
-
-
-
- Backend URL
- {{ connectedFacilityBackend }} change
-
-
- Connection Status
- Connected
-
-
- Version
- {{ connectedFacilityBackendVersion }}
-
-
+
+
+
+
+
+ ID |
+ {{element.transferId}}
+ |
+
+
+
+ Status |
+ {{element.status}}
+ |
+
+
+
+ Action |
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+ Backend URL
+ {{ connectedFacilityBackend }} change
+
+
+ Connection Status
+ Connected
+
+
+ Version
+ {{ connectedFacilityBackendVersion
+ }}
+
+
+
+
+ Todo
+
+
+
+
+ Create new transfer
-
+
Ingest Dataset
@@ -62,7 +113,7 @@
-
@@ -33,7 +33,7 @@
+ (click)="onClickRefreshTransferList()">
refresh
- Action |
+
+ Action
+ |
-
- delete
-
-
- pause_circle
-
+
+ delete
+
+
+ pause_circle
+
|
@@ -74,7 +76,7 @@
Backend URL
{{ connectedFacilityBackend }} change
+ (click)="onClickDisconnectIngestor()">change
Connection Status
@@ -87,39 +89,24 @@
-
- Todo
-
-
-
- add
- Create new transfer
-
+
- Ingest Dataset
+ New transfer
-
-
-
-
-
- Upload
-
-
-
+
+ add
+
diff --git a/src/app/ingestor/ingestor/ingestor.component.scss b/src/app/ingestor/ingestor/ingestor.component.scss
index 96cdeec1b..685d6ee35 100644
--- a/src/app/ingestor/ingestor/ingestor.component.scss
+++ b/src/app/ingestor/ingestor/ingestor.component.scss
@@ -1,10 +1,12 @@
+@use "sass:map";
+@use "@angular/material" as mat;
+
.ingestor-vertical-layout {
display: flex;
flex-direction: column;
gap: 1em;
}
-/* src/app/ingestor/ingestor.component.scss */
.ingestor-mixed-header {
display: flex;
justify-content: space-between;
@@ -13,4 +15,52 @@
.ingestor-close-button {
margin-left: auto;
-}
\ No newline at end of file
+}
+
+.form-full-width {
+ width: 100%;
+}
+
+mat-card {
+ margin: 1em;
+
+ .section-icon {
+ height: auto !important;
+ width: auto !important;
+
+ mat-icon {
+ vertical-align: middle;
+ }
+ }
+}
+
+@mixin color($theme) {
+ $color-config: map-get($theme, "color");
+ $primary: map-get($color-config, "primary");
+ $header-1: map-get($color-config, "header-1");
+ $accent: map-get($color-config, "accent");
+ mat-card {
+ .organizational-header {
+ background-color: mat.get-color-from-palette($primary, "lighter");
+ }
+
+ .sample-header {
+ background-color: mat.get-color-from-palette($header-1, "lighter");
+ }
+
+ .instrument-header {
+ background-color: mat.get-color-from-palette($accent, "lighter");
+ }
+
+ .acquisition-header {
+ background-color: mat.get-color-from-palette($accent, "lighter");
+ }
+ }
+}
+
+@mixin theme($theme) {
+ $color-config: mat.get-color-config($theme);
+ @if $color-config != null {
+ @include color($theme);
+ }
+}
diff --git a/src/app/ingestor/ingestor/ingestor.component.ts b/src/app/ingestor/ingestor/ingestor.component.ts
index 55d4200fc..8daab0e07 100644
--- a/src/app/ingestor/ingestor/ingestor.component.ts
+++ b/src/app/ingestor/ingestor/ingestor.component.ts
@@ -1,58 +1,56 @@
-import { Component, OnInit, ViewChild } from "@angular/core";
-import { AppConfigService, HelpMessages } from "app-config.service";
+import { Component, inject, OnInit } from "@angular/core";
+import { AppConfigService } from "app-config.service";
import { HttpClient } from '@angular/common/http';
-import { IngestorMetadataEditorComponent } from '../ingestor-metadata-editor/ingestor-metadata-editor.component';
import { ActivatedRoute, Router } from '@angular/router';
import { INGESTOR_API_ENDPOINTS_V1 } from "./ingestor-api-endpoints";
+import { IngestorNewTransferDialogComponent } from "./dialog/ingestor.new-transfer-dialog";
+import { MatDialog } from "@angular/material/dialog";
+import { IngestorUserMetadataDialog } from "./dialog/ingestor.user-metadata-dialog";
+import { IngestorExtractorMetadataDialog } from "./dialog/ingestor.extractor-metadata-dialog";
+import { IngestorConfirmTransferDialog } from "./dialog/ingestor.confirm-transfer-dialog";
-interface TransferDataListEntry {
+interface ITransferDataListEntry {
transferId: string;
status: string;
}
+interface IIngestionRequestInformation {
+ filePath: string;
+ availableMethods: string[];
+ userMetaData: string;
+ extractorMetaData: string;
+}
+
@Component({
selector: "ingestor",
templateUrl: "./ingestor.component.html",
styleUrls: ["./ingestor.component.scss"],
})
export class IngestorComponent implements OnInit {
-
- @ViewChild(IngestorMetadataEditorComponent) metadataEditor: IngestorMetadataEditorComponent;
-
- appConfig = this.appConfigService.getConfig();
- facility: string | null = null;
- ingestManual: string | null = null;
- gettingStarted: string | null = null;
- shoppingCartEnabled = false;
- helpMessages: HelpMessages;
+ readonly dialog = inject(MatDialog);
filePath: string = '';
loading: boolean = false;
forwardFacilityBackend: string = '';
- createNewTransfer: boolean = false;
connectedFacilityBackend: string = '';
connectedFacilityBackendVersion: string = '';
connectingToFacilityBackend: boolean = false;
+
lastUsedFacilityBackends: string[] = [];
- transferDataSource: TransferDataListEntry[] = []; // List of files to be transferred
+
+ transferDataSource: ITransferDataListEntry[] = []; // List of files to be transferred
displayedColumns: string[] = ['transferId', 'status', 'actions'];
errorMessage: string = '';
returnValue: string = '';
+ metadataEditorData: string = ""; // TODO
+
constructor(public appConfigService: AppConfigService, private http: HttpClient, private route: ActivatedRoute, private router: Router) { }
ngOnInit() {
- this.facility = this.appConfig.facility;
- this.ingestManual = this.appConfig.ingestManual;
- this.helpMessages = new HelpMessages(
- this.appConfig.helpMessages?.gettingStarted,
- this.appConfig.helpMessages?.ingestManual,
- );
- this.gettingStarted = this.appConfig.gettingStarted;
this.connectingToFacilityBackend = true;
- this.createNewTransfer = false;
this.lastUsedFacilityBackends = this.loadLastUsedFacilityBackends();
this.transferDataSource = [];
// Get the GET parameter 'backendUrl' from the URL
@@ -98,20 +96,24 @@ export class IngestorComponent implements OnInit {
return true;
}
- async apiGetTransferList(): Promise {
- await this.http.get(this.connectedFacilityBackend + INGESTOR_API_ENDPOINTS_V1.TRANSFER).subscribe(
+ apiGetTransferList(page: number, pageSize: number, transferId?: string): void {
+ const params: any = {
+ page: page.toString(),
+ pageSize: pageSize.toString(),
+ };
+ if (transferId) {
+ params.transferId = transferId;
+ }
+ this.http.get(this.connectedFacilityBackend + INGESTOR_API_ENDPOINTS_V1.TRANSFER, { params }).subscribe(
response => {
console.log('Transfer list received', response);
- return response['transfers'];
+ this.transferDataSource = response['transfers'];
},
error => {
this.errorMessage += `${new Date().toLocaleString()}: ${error.message}]
`;
console.error('Request failed', error);
- return [];
}
);
-
- return [];
}
apiUpload() {
@@ -119,7 +121,7 @@ export class IngestorComponent implements OnInit {
this.returnValue = '';
const payload = {
filePath: this.filePath,
- metaData: this.metadataEditor.metadata
+ metaData: 'todo'//this.metadataEditor.metadata
};
console.log('Uploading', payload);
@@ -138,7 +140,7 @@ export class IngestorComponent implements OnInit {
);
}
- forwardToIngestorPage() {
+ onClickForwardToIngestorPage() {
if (this.forwardFacilityBackend) {
this.connectingToFacilityBackend = true;
@@ -152,7 +154,7 @@ export class IngestorComponent implements OnInit {
}
}
- disconnectIngestor() {
+ onClickDisconnectIngestor() {
this.returnValue = '';
this.connectedFacilityBackend = '';
// Remove the GET parameter 'backendUrl' from the URL
@@ -160,7 +162,7 @@ export class IngestorComponent implements OnInit {
}
// Helper functions
- selectFacilityBackend(facilityBackend: string) {
+ onClickSelectFacilityBackend(facilityBackend: string) {
this.forwardFacilityBackend = facilityBackend;
}
@@ -177,26 +179,65 @@ export class IngestorComponent implements OnInit {
this.errorMessage = '';
}
- openNewTransferDialog(): void {
- this.createNewTransfer = true;
- this.metadataEditor.clearMetadata();
+ onClickNext(step: number): void {
+ console.log('Next step', step);
+ this.dialog.closeAll();
+
+ let dialogRef = null;
+
+ switch (step) {
+ case 0:
+ dialogRef = this.dialog.open(IngestorNewTransferDialogComponent, {
+ data: { onClickNext: this.onClickNext.bind(this), metadataEditorData: this.metadataEditorData },
+ disableClose: true
+ });
+
+ break;
+ case 1:
+ dialogRef = this.dialog.open(IngestorUserMetadataDialog, {
+ data: { onClickNext: this.onClickNext.bind(this), metadataEditorData: this.metadataEditorData },
+ disableClose: true
+ });
+ break;
+ case 2:
+ dialogRef = this.dialog.open(IngestorExtractorMetadataDialog, {
+ data: { onClickNext: this.onClickNext.bind(this), metadataEditorData: this.metadataEditorData },
+ disableClose: true
+ });
+ break;
+ case 3:
+ dialogRef = this.dialog.open(IngestorConfirmTransferDialog, {
+ data: { onClickNext: this.onClickNext.bind(this), metadataEditorData: this.metadataEditorData },
+ disableClose: true
+ });
+ break;
+ default:
+ console.error('Unknown step', step);
+ }
+
+ // Error if the dialog reference is not set
+ if (dialogRef === null) return;
+
+ /*dialogRef.afterClosed().subscribe(result => {
+ console.log(`Dialog result: ${result}`);
+ });*/
}
- onRefreshTransferList(): void {
- const TEST_DATALIST: TransferDataListEntry[] = [
- { transferId: '1', status: 'In progress' },
- { transferId: '2', status: 'Done' },
- { transferId: '3', status: 'Failed' },
- ];
-
- this.transferDataSource = TEST_DATALIST;
- console.log(this.transferDataSource);
- // TODO activate when the API is ready
- //this.apiGetTransferList();
+ onClickRefreshTransferList(): void {
+ this.apiGetTransferList(1, 100);
}
onCancelTransfer(transferId: string) {
console.log('Cancel transfer', transferId);
- // TODO activate when the API is ready
+ this.http.delete(this.connectedFacilityBackend + INGESTOR_API_ENDPOINTS_V1.TRANSFER + '/' + transferId).subscribe(
+ response => {
+ console.log('Transfer cancelled', response);
+ this.apiGetTransferList(1, 100);
+ },
+ error => {
+ this.errorMessage += `${new Date().toLocaleString()}: ${error.message}
`;
+ console.error('Cancel transfer failed', error);
+ }
+ );
}
}
\ No newline at end of file
From dfec300977583c31bada51f5e54707ef9e9728b2 Mon Sep 17 00:00:00 2001
From: David Wiessner
Date: Tue, 3 Dec 2024 09:35:19 +0000
Subject: [PATCH 012/242] frontend update - improved json form integration
---
.../ingestor-metadata-editor-helper.ts | 24 +-
.../ingestor-metadata-editor-schematest.ts | 210 ------------------
.../ingestor-metadata-editor.component.ts | 2 +-
src/app/ingestor/ingestor.module.ts | 12 +-
...estor.confirm-transfer-dialog.component.ts | 39 ++++
.../ingestor.confirm-transfer-dialog.html | 3 +-
.../ingestor.confirm-transfer-dialog.ts | 27 ---
...tor.dialog-stepper.component.component.ts} | 0
...tor.extractor-metadata-dialog.component.ts | 44 ++++
.../ingestor.extractor-metadata-dialog.html | 44 +++-
.../ingestor.extractor-metadata-dialog.ts | 27 ---
.../ingestor.new-transfer-dialog.component.ts | 56 +++++
.../dialog/ingestor.new-transfer-dialog.html | 9 +-
.../dialog/ingestor.new-transfer-dialog.ts | 35 ---
...ngestor.user-metadata-dialog.component.ts} | 15 +-
.../dialog/ingestor.user-metadata-dialog.html | 2 +-
.../ingestor/ingestor/ingestor.component.html | 2 +-
.../ingestor/ingestor/ingestor.component.scss | 4 +
.../ingestor/ingestor/ingestor.component.ts | 52 +++--
19 files changed, 266 insertions(+), 341 deletions(-)
create mode 100644 src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.component.ts
delete mode 100644 src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.ts
rename src/app/ingestor/ingestor/dialog/{ingestor.dialog-stepper.component.ts => ingestor.dialog-stepper.component.component.ts} (100%)
create mode 100644 src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.component.ts
delete mode 100644 src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.ts
create mode 100644 src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.component.ts
delete mode 100644 src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.ts
rename src/app/ingestor/ingestor/dialog/{ingestor.user-metadata-dialog.ts => ingestor.user-metadata-dialog.component.ts} (67%)
diff --git a/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper.ts b/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper.ts
index 632419f9c..edecaf865 100644
--- a/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper.ts
+++ b/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper.ts
@@ -1,3 +1,5 @@
+import { IIngestionRequestInformation } from "ingestor/ingestor/ingestor.component";
+
export interface Schema {
type?: string;
properties?: {
@@ -19,8 +21,12 @@ export interface UISchema {
export class IngestorMetadaEditorHelper {
static generateUISchemaFromSchema(schema: string): UISchema {
const parsedSchema: Schema = JSON.parse(schema);
-
+
const flattenProperties = (properties: any, parentKey: string = ''): any[] => {
+ if (!properties) {
+ return [];
+ }
+
return Object.keys(properties).reduce((acc, key) => {
const property = properties[key];
const fullKey = parentKey ? `${parentKey}.${key}` : key;
@@ -47,7 +53,21 @@ export class IngestorMetadaEditorHelper {
type: 'VerticalLayout',
elements: flattenProperties(parsedSchema.properties)
};
-
+
return uischema;
}
+
+ static mergeUserAndExtractorMetadata(userMetadata: Object, extractorMetadata: Object, space: number): string {
+ return JSON.stringify({ ...userMetadata, ...extractorMetadata }, null, space);
+ }
+
+ static createEmptyRequestInformation = (): IIngestionRequestInformation => {
+ return {
+ selectedPath: '',
+ selectedMethod: '',
+ userMetaData: {},
+ extractorMetaData: {},
+ mergedMetaDataString: ''
+ };
+ };
};
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest.ts b/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest.ts
index 8ed4d8d0e..05b606f41 100644
--- a/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest.ts
+++ b/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest.ts
@@ -206,216 +206,6 @@ export const schema_mask2 = {
},
description: 'List of instruments used in the project',
},
- organizational: {
- type: 'object',
- properties: {
- id: {
- type: 'string',
- },
- title: {
- type: 'string',
- },
- description: {
- type: 'string',
- },
- status: {
- type: 'string',
- enum: ['active', 'completed', 'archived'],
- },
- priority: {
- type: 'integer',
- minimum: 1,
- maximum: 5,
- },
- first_name: {
- type: 'string',
- description: 'first name',
- },
- work_status: {
- type: 'boolean',
- description: 'work status',
- },
- email: {
- type: 'string',
- description: 'email',
- pattern: '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$',
- },
- work_phone: {
- type: 'string',
- description: 'work phone',
- },
- name: {
- type: 'string',
- description: 'name',
- },
- name_org: {
- type: 'string',
- description: 'Name of the organization',
- },
- type_org: {
- type: 'string',
- description: 'Type of organization, academic, commercial, governmental, etc.',
- enum: ['Academic', 'Commercial', 'Government', 'Other'],
- },
- country: {
- type: 'string',
- description: 'Country of the institution',
- },
- role: {
- type: 'string',
- description: 'Role of the author, for example principal investigator',
- },
- orcid: {
- type: 'string',
- description: 'ORCID of the author, a type of unique identifier',
- },
- funder_name: {
- type: 'string',
- description: 'funding organization/person.',
- },
- start_date: {
- type: 'string',
- format: 'date',
- description: 'start date',
- },
- end_date: {
- type: 'string',
- format: 'date',
- description: 'end date',
- },
- budget: {
- type: 'number',
- description: 'budget',
- },
- project_id: {
- type: 'string',
- description: 'project id',
- },
- grants: {
- type: 'array',
- items: {
- type: 'object',
- properties: {
- grant_name: {
- type: 'string',
- description: 'name of the grant',
- },
- start_date: {
- type: 'string',
- format: 'date',
- description: 'start date',
- },
- end_date: {
- type: 'string',
- format: 'date',
- description: 'end date',
- },
- budget: {
- type: 'number',
- description: 'budget',
- },
- project_id: {
- type: 'string',
- description: 'project id',
- },
- country: {
- type: 'string',
- description: 'Country of the institution',
- },
- },
- },
- description: 'List of grants associated with the project',
- },
- authors: {
- type: 'array',
- items: {
- type: 'object',
- properties: {
- first_name: {
- type: 'string',
- description: 'first name',
- },
- work_status: {
- type: 'boolean',
- description: 'work status',
- },
- email: {
- type: 'string',
- description: 'email',
- pattern: '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$',
- },
- work_phone: {
- type: 'string',
- description: 'work phone',
- },
- name: {
- type: 'string',
- description: 'name',
- },
- name_org: {
- type: 'string',
- description: 'Name of the organization',
- },
- type_org: {
- type: 'string',
- description: 'Type of organization, academic, commercial, governmental, etc.',
- enum: ['Academic', 'Commercial', 'Government', 'Other'],
- },
- country: {
- type: 'string',
- description: 'Country of the institution',
- },
- role: {
- type: 'string',
- description: 'Role of the author, for example principal investigator',
- },
- orcid: {
- type: 'string',
- description: 'ORCID of the author, a type of unique identifier',
- },
- },
- },
- description: 'List of authors associated with the project',
- },
- instruments: {
- type: 'array',
- items: {
- type: 'object',
- properties: {
- microscope: {
- type: 'string',
- description: 'Name/Type of the Microscope',
- },
- illumination: {
- type: 'string',
- description: 'Mode of illumination used during data collection',
- },
- imaging: {
- type: 'string',
- description: 'Mode of imaging used during data collection',
- },
- electron_source: {
- type: 'string',
- description: 'Type of electron source used in the microscope, such as FEG',
- },
- acceleration_voltage: {
- type: 'number',
- description: 'Voltage used for the electron acceleration, in kV',
- },
- c2_aperture: {
- type: 'number',
- description: 'C2 aperture size used in data acquisition, in µm',
- },
- cs: {
- type: 'number',
- description: 'Spherical aberration of the instrument, in mm',
- },
- },
- },
- description: 'List of instruments used in the project',
- },
- },
- },
},
required: ['id', 'title', 'status', 'name', 'email', 'work_phone', 'orcid', 'country', 'type_org', 'name_org'],
};
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor.component.ts b/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor.component.ts
index 56b2a9fc3..65b7f330c 100644
--- a/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor.component.ts
+++ b/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor.component.ts
@@ -14,7 +14,7 @@ import { IngestorMetadaEditorHelper, Schema, UISchema } from './ingestor-metadat
})
export class IngestorMetadataEditorComponent implements OnChanges {
- @Input() data: string;
+ @Input() data: Object;
@Input() schema: Schema;
@Output() dataChange = new EventEmitter();
diff --git a/src/app/ingestor/ingestor.module.ts b/src/app/ingestor/ingestor.module.ts
index c2248030e..359e3dd50 100644
--- a/src/app/ingestor/ingestor.module.ts
+++ b/src/app/ingestor/ingestor.module.ts
@@ -16,14 +16,15 @@ import { MatTableModule } from "@angular/material/table";
import { MatDialogModule } from "@angular/material/dialog";
import { MatSelectModule } from "@angular/material/select";
import { MatOptionModule } from "@angular/material/core";
-import { IngestorNewTransferDialogComponent } from "./ingestor/dialog/ingestor.new-transfer-dialog";
-import { IngestorUserMetadataDialog } from "./ingestor/dialog/ingestor.user-metadata-dialog";
+import { MatAutocompleteModule } from "@angular/material/autocomplete";
+import { IngestorNewTransferDialogComponent } from "./ingestor/dialog/ingestor.new-transfer-dialog.component";
+import { IngestorUserMetadataDialog } from "./ingestor/dialog/ingestor.user-metadata-dialog.component";
import { JsonFormsModule } from '@jsonforms/angular';
import { JsonFormsAngularMaterialModule } from "@jsonforms/angular-material";
-import { IngestorExtractorMetadataDialog } from "./ingestor/dialog/ingestor.extractor-metadata-dialog";
-import { IngestorConfirmTransferDialog } from "./ingestor/dialog/ingestor.confirm-transfer-dialog";
+import { IngestorExtractorMetadataDialog } from "./ingestor/dialog/ingestor.extractor-metadata-dialog.component";
+import { IngestorConfirmTransferDialog } from "./ingestor/dialog/ingestor.confirm-transfer-dialog.component";
import { MatStepperModule } from "@angular/material/stepper";
-import { IngestorDialogStepperComponent } from "./ingestor/dialog/ingestor.dialog-stepper.component";
+import { IngestorDialogStepperComponent } from "./ingestor/dialog/ingestor.dialog-stepper.component.component";
@NgModule({
declarations: [
@@ -52,6 +53,7 @@ import { IngestorDialogStepperComponent } from "./ingestor/dialog/ingestor.dialo
MatSelectModule,
MatOptionModule,
MatStepperModule,
+ MatAutocompleteModule,
JsonFormsModule,
JsonFormsAngularMaterialModule,
],
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.component.ts b/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.component.ts
new file mode 100644
index 000000000..d214fed38
--- /dev/null
+++ b/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.component.ts
@@ -0,0 +1,39 @@
+import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
+import { MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
+import { IIngestionRequestInformation } from '../ingestor.component';
+import { connectableObservableDescriptor } from 'rxjs/internal/observable/ConnectableObservable';
+import { IngestorMetadaEditorHelper } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper';
+
+@Component({
+ selector: 'ingestor.confirm-transfer-dialog',
+ templateUrl: 'ingestor.confirm-transfer-dialog.html',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ styleUrls: ['../ingestor.component.scss'],
+})
+
+export class IngestorConfirmTransferDialog {
+ createNewTransferData: IIngestionRequestInformation = IngestorMetadaEditorHelper.createEmptyRequestInformation();
+ provideMergeMetaData: string = '';
+
+ constructor(public dialog: MatDialog, @Inject(MAT_DIALOG_DATA) public data: any) {
+ this.createNewTransferData = data.createNewTransferData;
+ }
+
+ ngOnInit() {
+ const space = 2;
+ this.provideMergeMetaData = IngestorMetadaEditorHelper.mergeUserAndExtractorMetadata(this.createNewTransferData.userMetaData, this.createNewTransferData.extractorMetaData, space);
+ }
+
+ onClickBack(): void {
+ if (this.data && this.data.onClickNext) {
+ this.data.onClickNext(2); // Beispielwert für den Schritt
+ }
+ }
+
+ onClickConfirm(): void {
+ if (this.data && this.data.onClickNext) {
+ this.createNewTransferData.mergedMetaDataString = this.provideMergeMetaData;
+ this.data.onClickConfirm();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.html b/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.html
index 45d7bcc19..52dfdddc6 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.html
+++ b/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.html
@@ -10,8 +10,9 @@
Confirm Metadata
+
-
+
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.ts b/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.ts
deleted file mode 100644
index 4e5521049..000000000
--- a/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import {ChangeDetectionStrategy, Component, Inject} from '@angular/core';
-import { MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
-
-@Component({
- selector: 'ingestor.confirm-transfer-dialog',
- templateUrl: 'ingestor.confirm-transfer-dialog.html',
- changeDetection: ChangeDetectionStrategy.OnPush,
- styleUrls: ['../ingestor.component.scss'],
-})
-
-export class IngestorConfirmTransferDialog {
- constructor(public dialog: MatDialog, @Inject(MAT_DIALOG_DATA) public data: any) {}
-
- onClickBack(): void {
- console.log('Next button clicked');
- if (this.data && this.data.onClickNext) {
- this.data.onClickNext(2); // Beispielwert für den Schritt
- }
- }
-
- onClickConfirm(): void {
- console.log('Confirm button clicked');
- if (this.data && this.data.onClickNext) {
- this.data.onClickConfirm();
- }
- }
-}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.dialog-stepper.component.ts b/src/app/ingestor/ingestor/dialog/ingestor.dialog-stepper.component.component.ts
similarity index 100%
rename from src/app/ingestor/ingestor/dialog/ingestor.dialog-stepper.component.ts
rename to src/app/ingestor/ingestor/dialog/ingestor.dialog-stepper.component.component.ts
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.component.ts b/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.component.ts
new file mode 100644
index 000000000..e37ebd7e7
--- /dev/null
+++ b/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.component.ts
@@ -0,0 +1,44 @@
+import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
+import { MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
+import { IIngestionRequestInformation } from '../ingestor.component';
+import { IngestorMetadaEditorHelper, Schema } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper';
+
+@Component({
+ selector: 'ingestor.extractor-metadata-dialog',
+ templateUrl: 'ingestor.extractor-metadata-dialog.html',
+ styleUrls: ['../ingestor.component.scss'],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+
+export class IngestorExtractorMetadataDialog {
+ metadataSchema: Schema;
+ createNewTransferData: IIngestionRequestInformation = IngestorMetadaEditorHelper.createEmptyRequestInformation();
+
+ waitForExtractedMetaData: boolean = true;
+
+ constructor(public dialog: MatDialog, @Inject(MAT_DIALOG_DATA) public data: any) {
+ this.metadataSchema = {};
+ this.createNewTransferData = data.createNewTransferData;
+ }
+
+ ngOnInit() {
+ this.waitForExtractedMetaData = false;
+ }
+
+
+ onClickBack(): void {
+ if (this.data && this.data.onClickNext) {
+ this.data.onClickNext(1); // Beispielwert für den Schritt
+ }
+ }
+
+ onClickNext(): void {
+ if (this.data && this.data.onClickNext) {
+ this.data.onClickNext(3); // Beispielwert für den Schritt
+ }
+ }
+
+ onDataChange(event: any) {
+ this.createNewTransferData.extractorMetaData = event;
+ }
+}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.html b/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.html
index ef83ca5d4..6366b1d43 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.html
+++ b/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.html
@@ -2,16 +2,52 @@
Correct dataset-specific metadata
-
+
close
-
-
+
+
+
Wait for ingestor...
+
+
+
Back
- Next
+ Next
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.ts b/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.ts
deleted file mode 100644
index c636b2654..000000000
--- a/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import {ChangeDetectionStrategy, Component, Inject} from '@angular/core';
-import { MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
-
-@Component({
- selector: 'ingestor.extractor-metadata-dialog',
- templateUrl: 'ingestor.extractor-metadata-dialog.html',
- styleUrls: ['../ingestor.component.scss'],
- changeDetection: ChangeDetectionStrategy.OnPush,
-})
-
-export class IngestorExtractorMetadataDialog {
- constructor(public dialog: MatDialog, @Inject(MAT_DIALOG_DATA) public data: any) {}
-
- onClickBack(): void {
- console.log('Next button clicked');
- if (this.data && this.data.onClickNext) {
- this.data.onClickNext(1); // Beispielwert für den Schritt
- }
- }
-
- onClickNext(): void {
- console.log('Next button clicked');
- if (this.data && this.data.onClickNext) {
- this.data.onClickNext(3); // Beispielwert für den Schritt
- }
- }
-}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.component.ts b/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.component.ts
new file mode 100644
index 000000000..352663e37
--- /dev/null
+++ b/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.component.ts
@@ -0,0 +1,56 @@
+import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core';
+import { MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
+import { HttpClient } from '@angular/common/http';
+import { IIngestionRequestInformation } from '../ingestor.component'
+import { IngestorMetadaEditorHelper } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper';
+
+@Component({
+ selector: 'ingestor.new-transfer-dialog',
+ templateUrl: 'ingestor.new-transfer-dialog.html',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ styleUrls: ['../ingestor.component.scss']
+})
+
+export class IngestorNewTransferDialogComponent implements OnInit {
+ extractionMethods: string[] = [];
+ availableFilePaths: string[] = [];
+
+ createNewTransferData: IIngestionRequestInformation = IngestorMetadaEditorHelper.createEmptyRequestInformation();
+
+ constructor(public dialog: MatDialog, @Inject(MAT_DIALOG_DATA) public data: any, private http: HttpClient) {
+ this.createNewTransferData = data.createNewTransferData;
+ }
+
+ ngOnInit(): void {
+ this.apiGetExtractionMethods();
+ this.apiGetAvailableFilePaths();
+ }
+
+ apiGetExtractionMethods(): void {
+ // Get reqeuest auf den Extractor endpoint
+ /*this.http.get('INGESTOR_API_ENDPOINTS_V1.extractor').subscribe((response: any) => {
+ this.extractionMethods = response;
+ console.log('Extraktoren geladen:', this.extractionMethods);
+ });*/
+
+ const fakeData = ['Extraktor 1', 'Extraktor 2', 'Extraktor 3'];
+ this.extractionMethods = fakeData;
+ }
+
+ apiGetAvailableFilePaths(): void {
+ // Get request auf den Dataset endpoint
+ /*this.http.get('INGESTOR_API_ENDPOINTS_V1.dataset').subscribe((response: any) => {
+ this.availableFilePaths = response;
+ console.log('Pfade geladen:', this.availableFilePaths);
+ });*/
+
+ const fakeData = ['Path 1', 'Path 2', 'Path 3'];
+ this.availableFilePaths = fakeData;
+ }
+
+ onClickNext(): void {
+ if (this.data && this.data.onClickNext) {
+ this.data.onClickNext(1); // Open next dialog
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.html b/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.html
index a054ec9e3..16675bd3d 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.html
+++ b/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.html
@@ -14,14 +14,19 @@
File Path
-
+
+
+
+ {{ method }}
+
+
Extraction Method
-
+
{{ method }}
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.ts b/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.ts
deleted file mode 100644
index 09464dc94..000000000
--- a/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import {ChangeDetectionStrategy, Component, Inject, OnInit} from '@angular/core';
-import { MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
-import { HttpClient } from '@angular/common/http';
-
-@Component({
- selector: 'ingestor.new-transfer-dialog',
- templateUrl: 'ingestor.new-transfer-dialog.html',
- changeDetection: ChangeDetectionStrategy.OnPush,
- styleUrls: ['../ingestor.component.scss']
-})
-
-export class IngestorNewTransferDialogComponent implements OnInit {
- filePath: string = '';
- selectedMethod: string = '';
- extractionMethods: string[] = [];
-
- constructor(public dialog: MatDialog, @Inject(MAT_DIALOG_DATA) public data: any, private http: HttpClient) {}
-
- ngOnInit(): void {
- console.log('Initialisieren');
- /*this.http.get('INGESTOR_API_ENDPOINTS_V1.extractor').subscribe((response: any) => {
- this.extractionMethods = response;
- console.log('Extraktoren geladen:', this.extractionMethods);
- });*/
-
- this.extractionMethods = ['Extraktor 1', 'Extraktor 2', 'Extraktor 3'];
- }
-
- onClickNext(): void {
- console.log('Next button clicked');
- if (this.data && this.data.onClickNext) {
- this.data.onClickNext(1); // Beispielwert für den Schritt
- }
- }
-}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.ts b/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.component.ts
similarity index 67%
rename from src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.ts
rename to src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.component.ts
index 3de23c296..c2fc72286 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.ts
+++ b/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.component.ts
@@ -1,7 +1,8 @@
import {ChangeDetectionStrategy, Component, Inject} from '@angular/core';
import { MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
-import { Schema } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper';
+import { IngestorMetadaEditorHelper, Schema } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper';
import { schema_mask2 } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest';
+import { IIngestionRequestInformation } from '../ingestor.component';
@Component({
selector: 'ingestor.user-metadata-dialog',
@@ -12,29 +13,27 @@ import { schema_mask2 } from 'ingestor/ingestor-metadata-editor/ingestor-metadat
export class IngestorUserMetadataDialog {
metadataSchema: Schema;
- metadataEditorData: string;
+
+ createNewTransferData: IIngestionRequestInformation = IngestorMetadaEditorHelper.createEmptyRequestInformation();
constructor(public dialog: MatDialog, @Inject(MAT_DIALOG_DATA) public data: any) {
this.metadataSchema = schema_mask2;
- this.metadataEditorData = data.metadataEditorData;
+ this.createNewTransferData = data.createNewTransferData;
}
onClickBack(): void {
- console.log('Next button clicked');
if (this.data && this.data.onClickNext) {
this.data.onClickNext(0); // Beispielwert für den Schritt
}
}
onClickNext(): void {
- console.log('Next button clicked');
if (this.data && this.data.onClickNext) {
this.data.onClickNext(2); // Beispielwert für den Schritt
}
}
- onDataChange(event: any) {
- this.metadataEditorData = event;
- console.log(event);
+ onDataChange(event: Object) {
+ this.createNewTransferData.userMetaData = event;
}
}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.html b/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.html
index f39a46a2b..4ec7ae4c1 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.html
+++ b/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.html
@@ -20,7 +20,7 @@
Organizational Information
-
diff --git a/src/app/ingestor/ingestor/ingestor.component.html b/src/app/ingestor/ingestor/ingestor.component.html
index 0f94f8fe9..187f6f2f7 100644
--- a/src/app/ingestor/ingestor/ingestor.component.html
+++ b/src/app/ingestor/ingestor/ingestor.component.html
@@ -104,7 +104,7 @@
+ (click)="onClickAddIngestion()">
add
diff --git a/src/app/ingestor/ingestor/ingestor.component.scss b/src/app/ingestor/ingestor/ingestor.component.scss
index 685d6ee35..defee924f 100644
--- a/src/app/ingestor/ingestor/ingestor.component.scss
+++ b/src/app/ingestor/ingestor/ingestor.component.scss
@@ -21,6 +21,10 @@
width: 100%;
}
+.metadata-preview {
+ height: 50vh !important;
+}
+
mat-card {
margin: 1em;
diff --git a/src/app/ingestor/ingestor/ingestor.component.ts b/src/app/ingestor/ingestor/ingestor.component.ts
index 8daab0e07..80dfd0772 100644
--- a/src/app/ingestor/ingestor/ingestor.component.ts
+++ b/src/app/ingestor/ingestor/ingestor.component.ts
@@ -3,22 +3,36 @@ import { AppConfigService } from "app-config.service";
import { HttpClient } from '@angular/common/http';
import { ActivatedRoute, Router } from '@angular/router';
import { INGESTOR_API_ENDPOINTS_V1 } from "./ingestor-api-endpoints";
-import { IngestorNewTransferDialogComponent } from "./dialog/ingestor.new-transfer-dialog";
+import { IngestorNewTransferDialogComponent } from "./dialog/ingestor.new-transfer-dialog.component";
import { MatDialog } from "@angular/material/dialog";
-import { IngestorUserMetadataDialog } from "./dialog/ingestor.user-metadata-dialog";
-import { IngestorExtractorMetadataDialog } from "./dialog/ingestor.extractor-metadata-dialog";
-import { IngestorConfirmTransferDialog } from "./dialog/ingestor.confirm-transfer-dialog";
+import { IngestorUserMetadataDialog } from "./dialog/ingestor.user-metadata-dialog.component";
+import { IngestorExtractorMetadataDialog } from "./dialog/ingestor.extractor-metadata-dialog.component";
+import { IngestorConfirmTransferDialog } from "./dialog/ingestor.confirm-transfer-dialog.component";
+import { IngestorMetadaEditorHelper } from "ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper";
interface ITransferDataListEntry {
transferId: string;
status: string;
}
-interface IIngestionRequestInformation {
- filePath: string;
- availableMethods: string[];
- userMetaData: string;
- extractorMetaData: string;
+interface ISciCatHeader {
+ datasetName: string;
+ description: string;
+ creationLocation: string;
+ dataFormat: string;
+ ownerGroup: string;
+ type: string;
+ license: string;
+ keywords: string[];
+ scientificMetadata: string;
+}
+
+export interface IIngestionRequestInformation {
+ selectedPath: string;
+ selectedMethod: string;
+ userMetaData: Object;
+ extractorMetaData: Object;
+ mergedMetaDataString: string;
}
@Component({
@@ -45,7 +59,7 @@ export class IngestorComponent implements OnInit {
errorMessage: string = '';
returnValue: string = '';
- metadataEditorData: string = ""; // TODO
+ createNewTransferData: IIngestionRequestInformation = IngestorMetadaEditorHelper.createEmptyRequestInformation();
constructor(public appConfigService: AppConfigService, private http: HttpClient, private route: ActivatedRoute, private router: Router) { }
@@ -120,8 +134,8 @@ export class IngestorComponent implements OnInit {
this.loading = true;
this.returnValue = '';
const payload = {
- filePath: this.filePath,
- metaData: 'todo'//this.metadataEditor.metadata
+ filePath: this.createNewTransferData.selectedPath,
+ metaData: this.createNewTransferData.mergedMetaDataString,
};
console.log('Uploading', payload);
@@ -179,8 +193,12 @@ export class IngestorComponent implements OnInit {
this.errorMessage = '';
}
+ onClickAddIngestion(): void {
+ this.createNewTransferData = IngestorMetadaEditorHelper.createEmptyRequestInformation();
+ this.onClickNext(0);
+ }
+
onClickNext(step: number): void {
- console.log('Next step', step);
this.dialog.closeAll();
let dialogRef = null;
@@ -188,26 +206,26 @@ export class IngestorComponent implements OnInit {
switch (step) {
case 0:
dialogRef = this.dialog.open(IngestorNewTransferDialogComponent, {
- data: { onClickNext: this.onClickNext.bind(this), metadataEditorData: this.metadataEditorData },
+ data: { onClickNext: this.onClickNext.bind(this), createNewTransferData: this.createNewTransferData },
disableClose: true
});
break;
case 1:
dialogRef = this.dialog.open(IngestorUserMetadataDialog, {
- data: { onClickNext: this.onClickNext.bind(this), metadataEditorData: this.metadataEditorData },
+ data: { onClickNext: this.onClickNext.bind(this), createNewTransferData: this.createNewTransferData },
disableClose: true
});
break;
case 2:
dialogRef = this.dialog.open(IngestorExtractorMetadataDialog, {
- data: { onClickNext: this.onClickNext.bind(this), metadataEditorData: this.metadataEditorData },
+ data: { onClickNext: this.onClickNext.bind(this), createNewTransferData: this.createNewTransferData },
disableClose: true
});
break;
case 3:
dialogRef = this.dialog.open(IngestorConfirmTransferDialog, {
- data: { onClickNext: this.onClickNext.bind(this), metadataEditorData: this.metadataEditorData },
+ data: { onClickNext: this.onClickNext.bind(this), createNewTransferData: this.createNewTransferData },
disableClose: true
});
break;
From 7f5847f26c35887d14a57f98ed5c703b76fe4303 Mon Sep 17 00:00:00 2001
From: David Wiessner
Date: Tue, 3 Dec 2024 10:39:43 +0000
Subject: [PATCH 013/242] Assignment of the input menus to the appropriate
metadata
---
.../ingestor-metadata-editor-helper.ts | 1 +
.../ingestor-metadata-editor-schematest.ts | 480 ++++++++++++++----
.../ingestor/ingestor/_ingestor-theme.scss | 39 ++
...estor.confirm-transfer-dialog.component.ts | 43 +-
...tor.extractor-metadata-dialog.component.ts | 15 +-
.../ingestor.extractor-metadata-dialog.html | 11 +-
...ingestor.user-metadata-dialog.component.ts | 23 +-
.../dialog/ingestor.user-metadata-dialog.html | 19 +-
.../ingestor/ingestor/ingestor.component.scss | 36 +-
.../ingestor/ingestor/ingestor.component.ts | 15 +-
src/styles.scss | 2 +
11 files changed, 514 insertions(+), 170 deletions(-)
create mode 100644 src/app/ingestor/ingestor/_ingestor-theme.scss
diff --git a/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper.ts b/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper.ts
index edecaf865..df2d8bc0a 100644
--- a/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper.ts
+++ b/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper.ts
@@ -65,6 +65,7 @@ export class IngestorMetadaEditorHelper {
return {
selectedPath: '',
selectedMethod: '',
+ scicatHeader: {},
userMetaData: {},
extractorMetaData: {},
mergedMetaDataString: ''
diff --git a/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest.ts b/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest.ts
index 05b606f41..630a06f27 100644
--- a/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest.ts
+++ b/src/app/ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest.ts
@@ -1,88 +1,6 @@
-export const schema_mask2 = {
+export const organizational_schema = {
type: 'object',
properties: {
- id: {
- type: 'string',
- },
- title: {
- type: 'string',
- },
- description: {
- type: 'string',
- },
- status: {
- type: 'string',
- enum: ['active', 'completed', 'archived'],
- },
- priority: {
- type: 'integer',
- minimum: 1,
- maximum: 5,
- },
- first_name: {
- type: 'string',
- description: 'first name',
- },
- work_status: {
- type: 'boolean',
- description: 'work status',
- },
- email: {
- type: 'string',
- description: 'email',
- pattern: '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$',
- },
- work_phone: {
- type: 'string',
- description: 'work phone',
- },
- name: {
- type: 'string',
- description: 'name',
- },
- name_org: {
- type: 'string',
- description: 'Name of the organization',
- },
- type_org: {
- type: 'string',
- description: 'Type of organization, academic, commercial, governmental, etc.',
- enum: ['Academic', 'Commercial', 'Government', 'Other'],
- },
- country: {
- type: 'string',
- description: 'Country of the institution',
- },
- role: {
- type: 'string',
- description: 'Role of the author, for example principal investigator',
- },
- orcid: {
- type: 'string',
- description: 'ORCID of the author, a type of unique identifier',
- },
- funder_name: {
- type: 'string',
- description: 'funding organization/person.',
- },
- start_date: {
- type: 'string',
- format: 'date',
- description: 'start date',
- },
- end_date: {
- type: 'string',
- format: 'date',
- description: 'end date',
- },
- budget: {
- type: 'number',
- description: 'budget',
- },
- project_id: {
- type: 'string',
- description: 'project id',
- },
grants: {
type: 'array',
items: {
@@ -169,43 +87,397 @@ export const schema_mask2 = {
},
description: 'List of authors associated with the project',
},
- instruments: {
+ funder: {
type: 'array',
items: {
type: 'object',
properties: {
- microscope: {
+ funder_name: {
type: 'string',
- description: 'Name/Type of the Microscope',
+ description: 'funding organization/person.',
},
- illumination: {
+ type_org: {
type: 'string',
- description: 'Mode of illumination used during data collection',
+ description: 'Type of organization, academic, commercial, governmental, etc.',
+ enum: ['Academic', 'Commercial', 'Government', 'Other'],
},
- imaging: {
+ country: {
type: 'string',
- description: 'Mode of imaging used during data collection',
+ description: 'Country of the institution',
},
- electron_source: {
+ },
+ },
+ description: 'Description of the project funding',
+ },
+ },
+ required: ['authors', 'funder'],
+};
+
+export const acquisition_schema = {
+ type: 'object',
+ properties: {
+ nominal_defocus: {
+ type: 'object',
+ description: 'Target defocus set, min and max values in µm.',
+ },
+ calibrated_defocus: {
+ type: 'object',
+ description: 'Machine estimated defocus, min and max values in µm. Has a tendency to be off.',
+ },
+ nominal_magnification: {
+ type: 'integer',
+ description: 'Magnification level as indicated by the instrument, no unit',
+ },
+ calibrated_magnification: {
+ type: 'integer',
+ description: 'Calculated magnification, no unit',
+ },
+ holder: {
+ type: 'string',
+ description: 'Speciman holder model',
+ },
+ holder_cryogen: {
+ type: 'string',
+ description: 'Type of cryogen used in the holder - if the holder is cooled seperately',
+ },
+ temperature_range: {
+ type: 'object',
+ description: 'Temperature during data collection, in K with min and max values.',
+ },
+ microscope_software: {
+ type: 'string',
+ description: 'Software used for instrument control',
+ },
+ detector: {
+ type: 'string',
+ description: 'Make and model of the detector used',
+ },
+ detector_mode: {
+ type: 'string',
+ description: 'Operating mode of the detector',
+ },
+ dose_per_movie: {
+ type: 'object',
+ description: 'Average dose per image/movie/tilt - given in electrons per square Angstrom',
+ },
+ energy_filter: {
+ type: 'object',
+ description: 'Whether an energy filter was used and its specifics.',
+ },
+ image_size: {
+ type: 'object',
+ description: 'The size of the image in pixels, height and width given.',
+ },
+ date_time: {
+ type: 'string',
+ description: 'Time and date of the data acquisition',
+ },
+ exposure_time: {
+ type: 'object',
+ description: 'Time of data acquisition per movie/tilt - in s',
+ },
+ cryogen: {
+ type: 'string',
+ description: 'Cryogen used in cooling the instrument and sample, usually nitrogen',
+ },
+ frames_per_movie: {
+ type: 'integer',
+ description: 'Number of frames that on average constitute a full movie, can be a bit hard to define for some detectors',
+ },
+ grids_imaged: {
+ type: 'integer',
+ description: 'Number of grids imaged for this project - here with qualifier during this data acquisition',
+ },
+ images_generated: {
+ type: 'integer',
+ description: 'Number of images generated total for this data collection - might need a qualifier for tilt series to determine whether full series or individual tilts are counted',
+ },
+ binning_camera: {
+ type: 'number',
+ description: 'Level of binning on the images applied during data collection',
+ },
+ pixel_size: {
+ type: 'object',
+ description: 'Pixel size, in Angstrom',
+ },
+ specialist_optics: {
+ type: 'object',
+ description: 'Any type of special optics, such as a phaseplate',
+ },
+ beamshift: {
+ type: 'object',
+ description: 'Movement of the beam above the sample for data collection purposes that does not require movement of the stage. Given in mrad.',
+ },
+ beamtilt: {
+ type: 'object',
+ description: 'Another way to move the beam above the sample for data collection purposes that does not require movement of the stage. Given in mrad.',
+ },
+ imageshift: {
+ type: 'object',
+ description: 'Movement of the Beam below the image in order to shift the image on the detector. Given in µm.',
+ },
+ beamtiltgroups: {
+ type: 'integer',
+ description: 'Number of Beamtilt groups present in this dataset - for optimized processing split dataset into groups of same tilt angle. Despite its name Beamshift is often used to achieve this result.',
+ },
+ gainref_flip_rotate: {
+ type: 'string',
+ description: 'Whether and how you have to flip or rotate the gainref in order to align with your acquired images',
+ },
+ },
+ required: ['detector', 'dose_per_movie', 'date_time', 'binning_camera', 'pixel_size'],
+};
+
+export const sample_schema = {
+ type: 'object',
+ properties: {
+ overall_molecule: {
+ type: 'object',
+ description: 'Description of the overall molecule',
+ properties: {
+ molecular_type: {
+ type: 'string',
+ description: 'Description of the overall molecular type, i.e., a complex',
+ },
+ name_sample: {
+ type: 'string',
+ description: 'Name of the full sample',
+ },
+ source: {
+ type: 'string',
+ description: 'Where the sample was taken from, i.e., natural host, recombinantly expressed, etc.',
+ },
+ molecular_weight: {
+ type: 'object',
+ description: 'Molecular weight in Da',
+ },
+ assembly: {
+ type: 'string',
+ description: 'What type of higher order structure your sample forms - if any.',
+ enum: ['FILAMENT', 'HELICAL ARRAY', 'PARTICLE'],
+ },
+ },
+ required: ['molecular_type', 'name_sample', 'source', 'assembly'],
+ },
+ molecule: {
+ type: 'array',
+ items: {
+ type: 'object',
+ properties: {
+ name_mol: {
type: 'string',
- description: 'Type of electron source used in the microscope, such as FEG',
+ description: 'Name of an individual molecule (often protein) in the sample',
},
- acceleration_voltage: {
- type: 'number',
- description: 'Voltage used for the electron acceleration, in kV',
+ molecular_type: {
+ type: 'string',
+ description: 'Description of the overall molecular type, i.e., a complex',
},
- c2_aperture: {
- type: 'number',
- description: 'C2 aperture size used in data acquisition, in µm',
+ molecular_class: {
+ type: 'string',
+ description: 'Class of the molecule',
+ enum: ['Antibiotic', 'Carbohydrate', 'Chimera', 'None of these'],
},
- cs: {
- type: 'number',
- description: 'Spherical aberration of the instrument, in mm',
+ sequence: {
+ type: 'string',
+ description: 'Full sequence of the sample as in the data, i.e., cleaved tags should also be removed from sequence here',
+ },
+ natural_source: {
+ type: 'string',
+ description: 'Scientific name of the natural host organism',
+ },
+ taxonomy_id_source: {
+ type: 'string',
+ description: 'Taxonomy ID of the natural source organism',
+ },
+ expression_system: {
+ type: 'string',
+ description: 'Scientific name of the organism used to produce the molecule of interest',
+ },
+ taxonomy_id_expression: {
+ type: 'string',
+ description: 'Taxonomy ID of the expression system organism',
+ },
+ gene_name: {
+ type: 'string',
+ description: 'Name of the gene of interest',
+ },
+ },
+ },
+ required: ['name_mol', 'molecular_type', 'molecular_class', 'sequence', 'natural_source', 'taxonomy_id_source', 'expression_system', 'taxonomy_id_expression'],
+ },
+ ligands: {
+ type: 'array',
+ items: {
+ type: 'object',
+ properties: {
+ present: {
+ type: 'boolean',
+ description: 'Whether the model contains any ligands',
+ },
+ smiles: {
+ type: 'string',
+ description: 'Provide a valid SMILES string of your ligand',
},
+ reference: {
+ type: 'string',
+ description: 'Link to a reference of your ligand, i.e., CCD, PubChem, etc.',
+ },
+ },
+ },
+ description: 'List of ligands associated with the sample',
+ },
+ specimen: {
+ type: 'object',
+ description: 'Description of the specimen',
+ properties: {
+ buffer: {
+ type: 'string',
+ description: 'Name/composition of the (chemical) sample buffer during grid preparation',
+ },
+ concentration: {
+ type: 'object',
+ description: 'Concentration of the (supra)molecule in the sample, in mg/ml',
+ },
+ ph: {
+ type: 'number',
+ description: 'pH of the sample buffer',
+ },
+ vitrification: {
+ type: 'boolean',
+ description: 'Whether the sample was vitrified',
+ },
+ vitrification_cryogen: {
+ type: 'string',
+ description: 'Which cryogen was used for vitrification',
+ },
+ humidity: {
+ type: 'object',
+ description: 'Environmental humidity just before vitrification, in %',
+ },
+ temperature: {
+ type: 'object',
+ description: 'Environmental temperature just before vitrification, in K',
+ minimum: 0.0,
+ },
+ staining: {
+ type: 'boolean',
+ description: 'Whether the sample was stained',
+ },
+ embedding: {
+ type: 'boolean',
+ description: 'Whether the sample was embedded',
+ },
+ shadowing: {
+ type: 'boolean',
+ description: 'Whether the sample was shadowed',
+ },
+ },
+ required: ['ph', 'vitrification', 'vitrification_cryogen', 'staining', 'embedding', 'shadowing'],
+ },
+ grid: {
+ type: 'object',
+ description: 'Description of the grid used',
+ properties: {
+ manufacturer: {
+ type: 'string',
+ description: 'Grid manufacturer',
+ },
+ material: {
+ type: 'string',
+ description: 'Material out of which the grid is made',
+ },
+ mesh: {
+ type: 'number',
+ description: 'Grid mesh in lines per inch',
+ },
+ film_support: {
+ type: 'boolean',
+ description: 'Whether a support film was used',
+ },
+ film_material: {
+ type: 'string',
+ description: 'Type of material the support film is made of',
+ },
+ film_topology: {
+ type: 'string',
+ description: 'Topology of the support film',
+ },
+ film_thickness: {
+ type: 'string',
+ description: 'Thickness of the support film',
+ },
+ pretreatment_type: {
+ type: 'string',
+ description: 'Type of pretreatment of the grid, i.e., glow discharge',
+ },
+ pretreatment_time: {
+ type: 'object',
+ description: 'Length of time of the pretreatment in s',
+ },
+ pretreatment_pressure: {
+ type: 'object',
+ description: 'Pressure of the chamber during pretreatment, in Pa',
+ },
+ pretreatment_atmosphere: {
+ type: 'string',
+ description: 'Atmospheric conditions in the chamber during pretreatment, i.e., addition of specific gases, etc.',
},
},
- description: 'List of instruments used in the project',
},
},
- required: ['id', 'title', 'status', 'name', 'email', 'work_phone', 'orcid', 'country', 'type_org', 'name_org'],
-};
\ No newline at end of file
+ required: ['overall_molecule', 'molecule', 'specimen', 'grid'],
+};
+
+export const instrument_schema = {
+ type: 'object',
+ properties: {
+ microscope: {
+ type: 'string',
+ description: 'Name/Type of the Microscope',
+ },
+ illumination: {
+ type: 'string',
+ description: 'Mode of illumination used during data collection',
+ },
+ imaging: {
+ type: 'string',
+ description: 'Mode of imaging used during data collection',
+ },
+ electron_source: {
+ type: 'string',
+ description: 'Type of electron source used in the microscope, such as FEG',
+ },
+ acceleration_voltage: {
+ type: 'object',
+ description: 'Voltage used for the electron acceleration, in kV',
+ },
+ c2_aperture: {
+ type: 'object',
+ description: 'C2 aperture size used in data acquisition, in µm',
+ },
+ cs: {
+ type: 'object',
+ description: 'Spherical aberration of the instrument, in mm',
+ },
+ },
+ required: ['microscope', 'illumination', 'imaging', 'electron_source', 'acceleration_voltage', 'cs'],
+};
+
+export const scicatheader_schema = {
+ type: "object",
+ properties: {
+ datasetName: { type: "string" },
+ description: { type: "string" },
+ creationLocation: { type: "string" },
+ dataFormat: { type: "string" },
+ ownerGroup: { type: "string" },
+ type: { type: "string" },
+ license: { type: "string" },
+ keywords: {
+ type: "array",
+ items: { type: "string" }
+ },
+ scientificMetadata: { type: "string" }
+ },
+ required: ["datasetName", "description", "creationLocation", "dataFormat", "ownerGroup", "type", "license", "keywords", "scientificMetadata"]
+}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/_ingestor-theme.scss b/src/app/ingestor/ingestor/_ingestor-theme.scss
new file mode 100644
index 000000000..39875ec92
--- /dev/null
+++ b/src/app/ingestor/ingestor/_ingestor-theme.scss
@@ -0,0 +1,39 @@
+@use "sass:map";
+@use "@angular/material" as mat;
+
+@mixin color($theme) {
+ $color-config: map-get($theme, "color");
+ $primary: map-get($color-config, "primary");
+ $header-1: map-get($color-config, "header-1");
+ $header-2: map-get($color-config, "header-2");
+ $header-3: map-get($color-config, "header-3");
+ $accent: map-get($color-config, "accent");
+ mat-card {
+ .scicat-header {
+ background-color: mat.get-color-from-palette($primary, "lighter");
+ }
+
+ .organizational-header {
+ background-color: mat.get-color-from-palette($header-1, "lighter");
+ }
+
+ .sample-header {
+ background-color: mat.get-color-from-palette($header-2, "lighter");
+ }
+
+ .instrument-header {
+ background-color: mat.get-color-from-palette($header-3, "lighter");
+ }
+
+ .acquisition-header {
+ background-color: mat.get-color-from-palette($accent, "lighter");
+ }
+ }
+}
+
+@mixin theme($theme) {
+ $color-config: mat.get-color-config($theme);
+ @if $color-config != null {
+ @include color($theme);
+ }
+}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.component.ts b/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.component.ts
index d214fed38..76637b90f 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.component.ts
+++ b/src/app/ingestor/ingestor/dialog/ingestor.confirm-transfer-dialog.component.ts
@@ -1,9 +1,27 @@
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { IIngestionRequestInformation } from '../ingestor.component';
-import { connectableObservableDescriptor } from 'rxjs/internal/observable/ConnectableObservable';
import { IngestorMetadaEditorHelper } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper';
+interface ISciCatHeader {
+ datasetName: string;
+ description: string;
+ creationLocation: string;
+ dataFormat: string;
+ ownerGroup: string;
+ type: string;
+ license: string;
+ keywords: string[];
+ scientificMetadata: IScientificMetadata;
+}
+
+interface IScientificMetadata {
+ organization: Object;
+ sample: Object;
+ acquisition: Object;
+ instrument: Object;
+}
+
@Component({
selector: 'ingestor.confirm-transfer-dialog',
templateUrl: 'ingestor.confirm-transfer-dialog.html',
@@ -20,8 +38,29 @@ export class IngestorConfirmTransferDialog {
}
ngOnInit() {
+ this.provideMergeMetaData = this.createMetaDataString();
+ }
+
+ createMetaDataString(): string {
const space = 2;
- this.provideMergeMetaData = IngestorMetadaEditorHelper.mergeUserAndExtractorMetadata(this.createNewTransferData.userMetaData, this.createNewTransferData.extractorMetaData, space);
+ const scicatMetadata: ISciCatHeader = {
+ datasetName: this.createNewTransferData.scicatHeader['datasetName'],
+ description: this.createNewTransferData.scicatHeader['description'],
+ creationLocation: this.createNewTransferData.scicatHeader['creationLocation'],
+ dataFormat: this.createNewTransferData.scicatHeader['dataFormat'],
+ ownerGroup: this.createNewTransferData.scicatHeader['ownerGroup'],
+ type: this.createNewTransferData.scicatHeader['type'],
+ license: this.createNewTransferData.scicatHeader['license'],
+ keywords: this.createNewTransferData.scicatHeader['keywords'],
+ scientificMetadata: {
+ organization: this.createNewTransferData.userMetaData['organization'],
+ sample: this.createNewTransferData.userMetaData['sample'],
+ acquisition: this.createNewTransferData.extractorMetaData['acquisition'],
+ instrument: this.createNewTransferData.extractorMetaData['instrument'],
+ },
+ };
+
+ return JSON.stringify(scicatMetadata, null, space);
}
onClickBack(): void {
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.component.ts b/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.component.ts
index e37ebd7e7..d09447139 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.component.ts
+++ b/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.component.ts
@@ -2,6 +2,7 @@ import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { IIngestionRequestInformation } from '../ingestor.component';
import { IngestorMetadaEditorHelper, Schema } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper';
+import { acquisition_schema, instrument_schema } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest';
@Component({
selector: 'ingestor.extractor-metadata-dialog',
@@ -11,13 +12,15 @@ import { IngestorMetadaEditorHelper, Schema } from 'ingestor/ingestor-metadata-e
})
export class IngestorExtractorMetadataDialog {
- metadataSchema: Schema;
+ metadataSchemaInstrument: Schema;
+ metadataSchemaAcquisition: Schema;
createNewTransferData: IIngestionRequestInformation = IngestorMetadaEditorHelper.createEmptyRequestInformation();
waitForExtractedMetaData: boolean = true;
constructor(public dialog: MatDialog, @Inject(MAT_DIALOG_DATA) public data: any) {
- this.metadataSchema = {};
+ this.metadataSchemaInstrument = instrument_schema;
+ this.metadataSchemaAcquisition = acquisition_schema;
this.createNewTransferData = data.createNewTransferData;
}
@@ -38,7 +41,11 @@ export class IngestorExtractorMetadataDialog {
}
}
- onDataChange(event: any) {
- this.createNewTransferData.extractorMetaData = event;
+ onDataChangeUserMetadataInstrument(event: any) {
+ this.createNewTransferData.extractorMetaData['instrument'] = event;
+ }
+
+ onDataChangeUserMetadataAcquisition(event: any) {
+ this.createNewTransferData.extractorMetaData['acquisition'] = event;
}
}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.html b/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.html
index 6366b1d43..c3283d3e0 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.html
+++ b/src/app/ingestor/ingestor/dialog/ingestor.extractor-metadata-dialog.html
@@ -27,19 +27,22 @@
Instrument Information
-
+
-
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.component.ts b/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.component.ts
index c2fc72286..e5532f221 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.component.ts
+++ b/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.component.ts
@@ -1,7 +1,7 @@
import {ChangeDetectionStrategy, Component, Inject} from '@angular/core';
import { MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
import { IngestorMetadaEditorHelper, Schema } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper';
-import { schema_mask2 } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest';
+import { organizational_schema, sample_schema, scicatheader_schema } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest';
import { IIngestionRequestInformation } from '../ingestor.component';
@Component({
@@ -12,12 +12,15 @@ import { IIngestionRequestInformation } from '../ingestor.component';
})
export class IngestorUserMetadataDialog {
- metadataSchema: Schema;
-
+ metadataSchemaOrganizational: Schema;
+ metadataSchemaSample: Schema;
+ scicatHeaderSchema: Schema;
createNewTransferData: IIngestionRequestInformation = IngestorMetadaEditorHelper.createEmptyRequestInformation();
constructor(public dialog: MatDialog, @Inject(MAT_DIALOG_DATA) public data: any) {
- this.metadataSchema = schema_mask2;
+ this.metadataSchemaOrganizational = organizational_schema;
+ this.metadataSchemaSample = sample_schema;
+ this.scicatHeaderSchema = scicatheader_schema;
this.createNewTransferData = data.createNewTransferData;
}
@@ -33,7 +36,15 @@ export class IngestorUserMetadataDialog {
}
}
- onDataChange(event: Object) {
- this.createNewTransferData.userMetaData = event;
+ onDataChangeUserMetadataOrganization(event: Object) {
+ this.createNewTransferData.userMetaData['organization'] = event;
+ }
+
+ onDataChangeUserMetadataSample(event: Object) {
+ this.createNewTransferData.userMetaData['sample'] = event;
+ }
+
+ onDataChangeUserScicatHeader(event: Object) {
+ this.createNewTransferData.scicatHeader = event;
}
}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.html b/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.html
index 4ec7ae4c1..abf714cf8 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.html
+++ b/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.html
@@ -12,6 +12,19 @@
-
+
-
Wait for ingestor...
+
+ Wait for the Ingestor...
+
-
+
@@ -51,6 +53,6 @@
Back
- Next
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.component.ts b/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.component.ts
index 352663e37..0433f6122 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.component.ts
+++ b/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.component.ts
@@ -1,8 +1,8 @@
import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
import { HttpClient } from '@angular/common/http';
-import { IIngestionRequestInformation } from '../ingestor.component'
-import { IngestorMetadaEditorHelper } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper';
+import { IExtractionMethod, IIngestionRequestInformation, IngestorMetadaEditorHelper } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper';
+import { INGESTOR_API_ENDPOINTS_V1 } from '../ingestor-api-endpoints';
@Component({
selector: 'ingestor.new-transfer-dialog',
@@ -12,13 +12,19 @@ import { IngestorMetadaEditorHelper } from 'ingestor/ingestor-metadata-editor/in
})
export class IngestorNewTransferDialogComponent implements OnInit {
- extractionMethods: string[] = [];
+ extractionMethods: IExtractionMethod[] = [];
availableFilePaths: string[] = [];
+ backendURL: string = '';
+ extractionMethodsError: string = '';
+ availableFilePathsError: string = '';
+
+ uiNextButtonReady: boolean = false;
createNewTransferData: IIngestionRequestInformation = IngestorMetadaEditorHelper.createEmptyRequestInformation();
constructor(public dialog: MatDialog, @Inject(MAT_DIALOG_DATA) public data: any, private http: HttpClient) {
this.createNewTransferData = data.createNewTransferData;
+ this.backendURL = data.backendURL;
}
ngOnInit(): void {
@@ -26,26 +32,61 @@ export class IngestorNewTransferDialogComponent implements OnInit {
this.apiGetAvailableFilePaths();
}
- apiGetExtractionMethods(): void {
- // Get reqeuest auf den Extractor endpoint
- /*this.http.get('INGESTOR_API_ENDPOINTS_V1.extractor').subscribe((response: any) => {
- this.extractionMethods = response;
- console.log('Extraktoren geladen:', this.extractionMethods);
- });*/
+ set selectedPath(value: string) {
+ this.createNewTransferData.selectedPath = value;
+ this.validateNextButton();
+ }
+
+ get selectedPath(): string {
+ return this.createNewTransferData.selectedPath;
+ }
+
+ set selectedMethod(value: IExtractionMethod) {
+ this.createNewTransferData.selectedMethod = value;
+ this.validateNextButton();
+ }
- const fakeData = ['Extraktor 1', 'Extraktor 2', 'Extraktor 3'];
- this.extractionMethods = fakeData;
+ get selectedMethod(): IExtractionMethod {
+ return this.createNewTransferData.selectedMethod;
+ }
+
+ apiGetExtractionMethods(): void {
+ this.http.get(this.backendURL + INGESTOR_API_ENDPOINTS_V1.EXTRACTOR).subscribe(
+ (response: any) => {
+ if (response.methods && response.methods.length > 0) {
+ this.extractionMethods = response.methods;
+ }
+ else {
+ this.extractionMethodsError = 'No extraction methods found.';
+ }
+ },
+ (error: any) => {
+ this.extractionMethodsError = error.message;
+ console.error(this.extractionMethodsError);
+ }
+ );
}
apiGetAvailableFilePaths(): void {
- // Get request auf den Dataset endpoint
- /*this.http.get('INGESTOR_API_ENDPOINTS_V1.dataset').subscribe((response: any) => {
- this.availableFilePaths = response;
- console.log('Pfade geladen:', this.availableFilePaths);
- });*/
+ this.http.get(this.backendURL + INGESTOR_API_ENDPOINTS_V1.DATASET).subscribe(
+ (response: any) => {
+ if (response.datasets && response.datasets.length > 0) {
+ this.availableFilePaths = response.datasets;
+ }
+ else {
+ this.availableFilePathsError = 'No datasets found.';
+ }
+ },
+ (error: any) => {
+ this.availableFilePathsError = error.message;
+ console.error(this.availableFilePathsError);
+ }
+ );
+ }
- const fakeData = ['Path 1', 'Path 2', 'Path 3'];
- this.availableFilePaths = fakeData;
+ onClickRetryRequests(): void {
+ this.apiGetExtractionMethods();
+ this.apiGetAvailableFilePaths();
}
onClickNext(): void {
@@ -53,4 +94,8 @@ export class IngestorNewTransferDialogComponent implements OnInit {
this.data.onClickNext(1); // Open next dialog
}
}
+
+ validateNextButton(): void {
+ this.uiNextButtonReady = !!this.createNewTransferData.selectedPath && !!this.createNewTransferData.selectedMethod?.name;
+ }
}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.html b/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.html
index 16675bd3d..6bd1a6d73 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.html
+++ b/src/app/ingestor/ingestor/dialog/ingestor.new-transfer-dialog.html
@@ -14,29 +14,32 @@
File Path
-
+
-
- {{ method }}
+
+ {{ filePath }}
+ {{ availableFilePathsError }}
Extraction Method
-
+
- {{ method }}
+ {{ method.name }}
+ {{ extractionMethodsError }}
+ Retry
Cancel
- Next
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.component.ts b/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.component.ts
index e5532f221..cbf4cacd8 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.component.ts
+++ b/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.component.ts
@@ -1,8 +1,7 @@
import {ChangeDetectionStrategy, Component, Inject} from '@angular/core';
import { MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
-import { IngestorMetadaEditorHelper, Schema } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper';
+import { IIngestionRequestInformation, IngestorMetadaEditorHelper, Schema } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-helper';
import { organizational_schema, sample_schema, scicatheader_schema } from 'ingestor/ingestor-metadata-editor/ingestor-metadata-editor-schematest';
-import { IIngestionRequestInformation } from '../ingestor.component';
@Component({
selector: 'ingestor.user-metadata-dialog',
@@ -16,12 +15,37 @@ export class IngestorUserMetadataDialog {
metadataSchemaSample: Schema;
scicatHeaderSchema: Schema;
createNewTransferData: IIngestionRequestInformation = IngestorMetadaEditorHelper.createEmptyRequestInformation();
+ backendURL: string = '';
+
+ uiNextButtonReady: boolean = true; // Change to false when dev is ready
+
+ isCardContentVisible = {
+ scicat: true,
+ organizational: true,
+ sample: true
+ };
constructor(public dialog: MatDialog, @Inject(MAT_DIALOG_DATA) public data: any) {
- this.metadataSchemaOrganizational = organizational_schema;
- this.metadataSchemaSample = sample_schema;
+ const encodedSchema = data.createNewTransferData.selectedMethod.schema;
+ const decodedSchema = atob(encodedSchema);
+ const schema = JSON.parse(decodedSchema);
+
+ console.log(schema);
+ const resolvedSchema = IngestorMetadaEditorHelper.resolveRefs(schema, schema);
+
+ console.log(resolvedSchema);
+
+ const organizationalSchema = resolvedSchema.properties.organizational;
+ const sampleSchema = resolvedSchema.properties.sample;
+
+ console.log(organizationalSchema);
+ console.log(sampleSchema);
+
+ this.metadataSchemaOrganizational = organizationalSchema;
+ this.metadataSchemaSample = sampleSchema;
this.scicatHeaderSchema = scicatheader_schema;
this.createNewTransferData = data.createNewTransferData;
+ this.backendURL = data.backendURL;
}
onClickBack(): void {
@@ -47,4 +71,8 @@ export class IngestorUserMetadataDialog {
onDataChangeUserScicatHeader(event: Object) {
this.createNewTransferData.scicatHeader = event;
}
+
+ toggleCardContent(card: string): void {
+ this.isCardContentVisible[card] = !this.isCardContentVisible[card];
+ }
}
\ No newline at end of file
diff --git a/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.html b/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.html
index abf714cf8..8e3fd1914 100644
--- a/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.html
+++ b/src/app/ingestor/ingestor/dialog/ingestor.user-metadata-dialog.html
@@ -13,39 +13,45 @@
-
-
-
-
-
+
EMPIAR
diff --git a/src/app/datasets/dataset-detail/dataset-detail.component.scss b/src/app/datasets/dataset-detail/dataset-detail.component.scss
index efb4f1bdc..4ceac4289 100644
--- a/src/app/datasets/dataset-detail/dataset-detail.component.scss
+++ b/src/app/datasets/dataset-detail/dataset-detail.component.scss
@@ -52,8 +52,9 @@ mat-card {
margin: 1em 0 0 1em;
}
.emexport-button {
- margin: 1em 0 0 3em;
- background-color: hsla(185, 43%, 45%, 0.458);
+ margin: 1em 0 0 1em;
+ background-color: hsla(185, 43%, 45%, 0.858);
+ color: white;
}
.public-toggle {
margin: 1em 1em 0 0;
diff --git a/src/app/datasets/onedep/onedep.component.html b/src/app/datasets/onedep/onedep.component.html
index 822153b38..db0a8ec7a 100644
--- a/src/app/datasets/onedep/onedep.component.html
+++ b/src/app/datasets/onedep/onedep.component.html
@@ -1,26 +1,221 @@
-OneDep Component is working!
-
-
+
+
-
+
+
+
+ Name |
+ {{ dataset.datasetName || "-" }} |
+
+
+ Description |
+
+
+ |
+
+
+ PID |
+
+ {{ dataset.pid }}
+ |
+
+
+ Type |
+ {{dataset.type }} |
+
+
+ Creation Time |
+ {{ dataset.creationTime | date: "yyyy-MM-dd
+ HH:mm" }} |
+
+
+ Keywords |
+
+
+ {{ keyword }}
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+ showValue()
+
+
+
+
-
+
\ No newline at end of file
diff --git a/src/app/datasets/onedep/onedep.component.ts b/src/app/datasets/onedep/onedep.component.ts
index b1f0a3e4e..76f308fe1 100644
--- a/src/app/datasets/onedep/onedep.component.ts
+++ b/src/app/datasets/onedep/onedep.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from "@angular/core";
+import { Component, OnInit, ChangeDetectorRef } from "@angular/core";
import { AppConfigService, HelpMessages } from "app-config.service";
import { HttpClient } from '@angular/common/http';
import { ActivatedRoute, Router } from '@angular/router';
@@ -16,7 +16,12 @@ import {
} from "state-management/selectors/datasets.selectors";
import { Subscription } from "rxjs";
+import { string } from "mathjs";
+interface EmMethod {
+ value: string;
+ viewValue:string;
+}
@Component({
selector: 'onedep',
@@ -27,35 +32,43 @@ export class OneDepComponent implements OnInit {
appConfig = this.appConfigService.getConfig();
dataset: Dataset | undefined;
- cd$ = this.store.select(selectCurrentDataset);
form: FormGroup;
- //attachments$ = this.store.select(selectCurrentAttachments);
- // datasetWithout$ = this.store.select(selectCurrentDatasetWithoutFileInfo);
- // userProfile$ = this.store.select(selectProfile);
- // isAdmin$ = this.store.select(selectIsAdmin);
- // accessGroups$: Observable
= this.userProfile$.pipe(
- // map((profile) => (profile ? profile.accessGroups : [])),
- // );
private subscriptions: Subscription[] = [];
+ showAssociatedMapQuestion: boolean = false;
+ methodsList: EmMethod[] = [
+ {value:'helical', viewValue: 'Helical'},
+ {value:'single-particle', viewValue:'Single Particle'},
+ {value:'subtomogram-averaging',viewValue: 'Subtomogram Averaging'},
+ {value:'tomogram', viewValue: 'Tomogram'},
+ {value:'electron-cristallography', viewValue:'Electron Crystallography'},
+ ];
+ emMethod: string;
constructor(public appConfigService: AppConfigService,
private store: Store,
// private http: HttpClient,
// private route: ActivatedRoute,
// private router: Router,
- private fb: FormBuilder
+ private fb: FormBuilder,
) { }
ngOnInit() {
- console.log('init OneDep')
+ this.store.select(selectCurrentDataset).subscribe((dataset) => {
+ this.dataset = dataset;
+ });
this.form = this.fb.group({
datasetName: new FormControl("", [Validators.required]),
description: new FormControl("", [Validators.required]),
keywords: this.fb.array([]),
- });
- this.store.select(selectCurrentDataset).subscribe((dataset) => {
- this.dataset = dataset;
- });
+ deposingCoordinates:new FormControl(true),
+ associatedMap: new FormControl(false),
+ compositeMap:new FormControl(false),
+ emdbId:new FormControl(false),
+
+ })
+ }
+ showValue(){
+ console.log(this.form['deposingCoordinates'])
}
}
From 3de3fef7e7c8dee05db258eccf47dfb836374450 Mon Sep 17 00:00:00 2001
From: sofyalaski
Date: Thu, 31 Oct 2024 17:55:14 +0100
Subject: [PATCH 024/242] prepared dields for OneDep export
---
.../dataset-detail.component.html | 19 +-
.../dataset-detail.component.ts | 5 +
src/app/datasets/onedep/onedep.component.html | 382 ++++++++++++------
src/app/datasets/onedep/onedep.component.scss | 24 +-
src/app/datasets/onedep/onedep.component.ts | 87 +++-
5 files changed, 387 insertions(+), 130 deletions(-)
diff --git a/src/app/datasets/dataset-detail/dataset-detail.component.html b/src/app/datasets/dataset-detail/dataset-detail.component.html
index dd98f6e24..c5c6d5833 100644
--- a/src/app/datasets/dataset-detail/dataset-detail.component.html
+++ b/src/app/datasets/dataset-detail/dataset-detail.component.html
@@ -16,19 +16,20 @@
mat-raised-button
id="onedepBtn"
class="emexport-button"
+ *ngIf="hasOpenEMKeyword()"
(click)="onOneDepClick()"
>
OneDep
-
+
+ EMPIAR
+
Description |
-
+
|
@@ -40,8 +39,7 @@
Keywords |
-
+
{{ keyword }}
@@ -50,7 +48,7 @@
-
+
- -->
+
+
diff --git a/src/app/datasets/onedep/onedep.component.scss b/src/app/datasets/onedep/onedep.component.scss
index b862d7d64..71d65ed58 100644
--- a/src/app/datasets/onedep/onedep.component.scss
+++ b/src/app/datasets/onedep/onedep.component.scss
@@ -12,6 +12,9 @@ mat-card {
table {
th {
+ .questionnaire{
+ min-width: 20rem;
+ }
min-width: 10rem;
padding-right: 0.5rem;
text-align: left;
@@ -30,10 +33,29 @@ mat-card {
}
}
-
+ .EMDB-ID{
+ width: 15%;
+ }
+ .method-name{
+ width: 25%;
+ }
+ .file-types{
+ width:10%;
+ }
.full-width {
width: 100%;
}
+ .fileChooser{
+ margin-left: 0px;
+ }
+ .fileName {
+ margin-left: 10px;
+ white-space: nowrap;
+ }
+ .submitDep{
+ background-color: blueviolet;
+ }
}
+
}
\ No newline at end of file
diff --git a/src/app/datasets/onedep/onedep.component.ts b/src/app/datasets/onedep/onedep.component.ts
index 76f308fe1..16434c83f 100644
--- a/src/app/datasets/onedep/onedep.component.ts
+++ b/src/app/datasets/onedep/onedep.component.ts
@@ -36,6 +36,14 @@ export class OneDepComponent implements OnInit {
private subscriptions: Subscription[] = [];
showAssociatedMapQuestion: boolean = false;
+ connectedDepositionBackend: string = '';
+ connectedDepositionBackendVersion: string = '';
+ connectingToDepositionBackend: boolean = false;
+ lastUsedDepositionBackends: string[] = [];
+ forwardDepositionBackend: string = '';
+ errorMessage: string = '';
+
+
methodsList: EmMethod[] = [
{value:'helical', viewValue: 'Helical'},
{value:'single-particle', viewValue:'Single Particle'},
@@ -43,12 +51,15 @@ export class OneDepComponent implements OnInit {
{value:'tomogram', viewValue: 'Tomogram'},
{value:'electron-cristallography', viewValue:'Electron Crystallography'},
];
- emMethod: string;
+
+ selectedFile: { [key: string]: File | null } = {};
+
+
constructor(public appConfigService: AppConfigService,
private store: Store,
- // private http: HttpClient,
- // private route: ActivatedRoute,
- // private router: Router,
+ private http: HttpClient,
+ private route: ActivatedRoute,
+ private router: Router,
private fb: FormBuilder,
) { }
@@ -61,14 +72,76 @@ export class OneDepComponent implements OnInit {
datasetName: new FormControl("", [Validators.required]),
description: new FormControl("", [Validators.required]),
keywords: this.fb.array([]),
+ emMethod: new FormControl(""),
deposingCoordinates:new FormControl(true),
associatedMap: new FormControl(false),
compositeMap:new FormControl(false),
- emdbId:new FormControl(false),
+ emdbId:new FormControl(""),
+ pathToMainMap: new FormControl(""),
+ pathToHalfMap1: new FormControl(""),
+ pathToHalfMap2: new FormControl(""),
+ pathToMask: new FormControl(""),
+ pathToAdditionalMap: new FormControl(""),
+ pathToCoordinates: new FormControl(""),
+ pathToImage: new FormControl(""),
+ pathToCif: new FormControl(""),
+ pathToFSC: new FormControl(""),
})
+
+ this.connectingToDepositionBackend = true;
+ // Get the GET parameter 'backendUrl' from the URL
+ // this.route.queryParams.subscribe(params => {
+ // const backendUrl = params['backendUrl'];
+ // if (backendUrl) {
+ // this.connectToDepositionBackend(backendUrl);
+ // }
+ // else {
+ // this.connectingToDepositionBackend = false;
+ // }
+ // });
+ }
+
+ connectToDepositionBackend(): boolean {
+ var DepositionBackendUrl = "http://localhost:8080"
+ let DepositionBackendUrlCleaned = DepositionBackendUrl.slice();
+ // Check if last symbol is a slash and add version endpoint
+ if (!DepositionBackendUrlCleaned.endsWith('/')) {
+ DepositionBackendUrlCleaned += '/';
+ }
+
+ let DepositionBackendUrlVersion = DepositionBackendUrlCleaned;
+
+ // Try to connect to the facility backend/version to check if it is available
+ console.log('Connecting to facility backend: ' + DepositionBackendUrlVersion);
+ this.http.get(DepositionBackendUrlVersion).subscribe(
+ response => {
+ console.log('Connected to facility backend', response);
+ // If the connection is successful, store the connected facility backend URL
+ this.connectedDepositionBackend = DepositionBackendUrlCleaned;
+ this.connectingToDepositionBackend = false;
+ this.connectedDepositionBackendVersion = response['version'];
+ },
+ error => {
+ this.errorMessage += `${new Date().toLocaleString()}: ${error.message}
`;
+ console.error('Request failed', error);
+ this.connectedDepositionBackend = '';
+ this.connectingToDepositionBackend = false;
+ }
+ );
+
+ return true;
+ }
+
+ onFileSelected(event: Event, controlName: string) {
+ const input = event.target as HTMLInputElement;
+ if (input.files && input.files.length > 0) {
+ this.selectedFile[controlName] = input.files[0];
+ this.form.get(controlName)?.setValue(this.selectedFile[controlName].name);
+ }
}
- showValue(){
- console.log(this.form['deposingCoordinates'])
+ onDepositClick(){
+ const formData = this.form.value;
}
+
}
From 94bdd298f63b24c51d453018b84322fa0f1caeca Mon Sep 17 00:00:00 2001
From: sofyalaski
Date: Fri, 1 Nov 2024 16:34:27 +0100
Subject: [PATCH 025/242] connect to OneDep backend when going to onedep
---
.../dataset-detail.component.ts | 45 +++++++++++++++++
src/app/datasets/onedep/onedep.component.html | 4 +-
src/app/datasets/onedep/onedep.component.ts | 48 +++++--------------
3 files changed, 57 insertions(+), 40 deletions(-)
diff --git a/src/app/datasets/dataset-detail/dataset-detail.component.ts b/src/app/datasets/dataset-detail/dataset-detail.component.ts
index 3a3db36fd..30f76fa82 100644
--- a/src/app/datasets/dataset-detail/dataset-detail.component.ts
+++ b/src/app/datasets/dataset-detail/dataset-detail.component.ts
@@ -7,6 +7,7 @@ import { MatDialog } from "@angular/material/dialog";
import { DialogComponent } from "shared/modules/dialog/dialog.component";
import { combineLatest, fromEvent, Observable, Subscription } from "rxjs";
import { Store } from "@ngrx/store";
+import { HttpClient } from '@angular/common/http';
import { showMessageAction } from "state-management/actions/user.actions";
import {
@@ -90,6 +91,14 @@ export class DatasetDetailComponent
editEnabled = false;
show = false;
+
+ connectedDepositionBackend: string = '';
+ connectedDepositionBackendVersion: string = '';
+ connectingToDepositionBackend: boolean = false;
+ lastUsedDepositionBackends: string[] = [];
+ forwardDepositionBackend: string = '';
+ errorMessage: string = '';
+
@Output() emClick = new EventEmitter();
readonly separatorKeyCodes: number[] = [ENTER, COMMA, SPACE];
@@ -100,11 +109,14 @@ export class DatasetDetailComponent
private attachmentService: AttachmentService,
public dialog: MatDialog,
private store: Store,
+ private http: HttpClient,
private router: Router,
private fb: FormBuilder,
) {}
ngOnInit() {
+ this.connectingToDepositionBackend = true;
+
this.form = this.fb.group({
datasetName: new FormControl("", [Validators.required]),
description: new FormControl("", [Validators.required]),
@@ -324,4 +336,37 @@ export class DatasetDetailComponent
this.router.navigateByUrl("/datasets/" + id + "/empiar");
}
+
+ connectToDepositionBackend(): boolean {
+ var DepositionBackendUrl = "http://localhost:8080"
+ let DepositionBackendUrlCleaned = DepositionBackendUrl.slice();
+ // Check if last symbol is a slash and add version endpoint
+ if (!DepositionBackendUrlCleaned.endsWith('/')) {
+ DepositionBackendUrlCleaned += '/';
+ }
+
+ let DepositionBackendUrlVersion = DepositionBackendUrlCleaned;
+
+ // Try to connect to the facility backend/version to check if it is available
+ console.log('Connecting to facility backend: ' + DepositionBackendUrlVersion);
+ this.http.get(DepositionBackendUrlVersion).subscribe(
+ response => {
+ console.log('Connected to facility backend', response);
+ // If the connection is successful, store the connected facility backend URL
+ this.connectedDepositionBackend = DepositionBackendUrlCleaned;
+ this.connectingToDepositionBackend = false;
+ this.connectedDepositionBackendVersion = response['version'];
+ },
+ error => {
+ this.errorMessage += `${new Date().toLocaleString()}: ${error.message}
`;
+ console.error('Request failed', error);
+ this.connectedDepositionBackend = '';
+ this.connectingToDepositionBackend = false;
+ }
+ );
+
+ return true;
+ }
+
}
+
diff --git a/src/app/datasets/onedep/onedep.component.html b/src/app/datasets/onedep/onedep.component.html
index 7148f5362..62bf4c166 100644
--- a/src/app/datasets/onedep/onedep.component.html
+++ b/src/app/datasets/onedep/onedep.component.html
@@ -360,9 +360,7 @@
-
- connect
-
+
Start Deposition
diff --git a/src/app/datasets/onedep/onedep.component.ts b/src/app/datasets/onedep/onedep.component.ts
index 16434c83f..bb9f31e05 100644
--- a/src/app/datasets/onedep/onedep.component.ts
+++ b/src/app/datasets/onedep/onedep.component.ts
@@ -36,12 +36,12 @@ export class OneDepComponent implements OnInit {
private subscriptions: Subscription[] = [];
showAssociatedMapQuestion: boolean = false;
- connectedDepositionBackend: string = '';
- connectedDepositionBackendVersion: string = '';
- connectingToDepositionBackend: boolean = false;
- lastUsedDepositionBackends: string[] = [];
- forwardDepositionBackend: string = '';
- errorMessage: string = '';
+ // connectedDepositionBackend: string = '';
+ // connectedDepositionBackendVersion: string = '';
+ // connectingToDepositionBackend: boolean = false;
+ // lastUsedDepositionBackends: string[] = [];
+ // forwardDepositionBackend: string = '';
+ // errorMessage: string = '';
methodsList: EmMethod[] = [
@@ -89,7 +89,7 @@ export class OneDepComponent implements OnInit {
pathToFSC: new FormControl(""),
})
- this.connectingToDepositionBackend = true;
+ // this.connectingToDepositionBackend = true;
// Get the GET parameter 'backendUrl' from the URL
// this.route.queryParams.subscribe(params => {
// const backendUrl = params['backendUrl'];
@@ -102,36 +102,6 @@ export class OneDepComponent implements OnInit {
// });
}
- connectToDepositionBackend(): boolean {
- var DepositionBackendUrl = "http://localhost:8080"
- let DepositionBackendUrlCleaned = DepositionBackendUrl.slice();
- // Check if last symbol is a slash and add version endpoint
- if (!DepositionBackendUrlCleaned.endsWith('/')) {
- DepositionBackendUrlCleaned += '/';
- }
-
- let DepositionBackendUrlVersion = DepositionBackendUrlCleaned;
-
- // Try to connect to the facility backend/version to check if it is available
- console.log('Connecting to facility backend: ' + DepositionBackendUrlVersion);
- this.http.get(DepositionBackendUrlVersion).subscribe(
- response => {
- console.log('Connected to facility backend', response);
- // If the connection is successful, store the connected facility backend URL
- this.connectedDepositionBackend = DepositionBackendUrlCleaned;
- this.connectingToDepositionBackend = false;
- this.connectedDepositionBackendVersion = response['version'];
- },
- error => {
- this.errorMessage += `${new Date().toLocaleString()}: ${error.message}
`;
- console.error('Request failed', error);
- this.connectedDepositionBackend = '';
- this.connectingToDepositionBackend = false;
- }
- );
-
- return true;
- }
onFileSelected(event: Event, controlName: string) {
const input = event.target as HTMLInputElement;
@@ -142,6 +112,10 @@ export class OneDepComponent implements OnInit {
}
onDepositClick(){
const formData = this.form.value;
+ // need to properly catch the dataset details
+ console.log(this.dataset)
+ //return this.http.post(this.backendUrl, formData);
+
}
}
From f3a2ed404461104fbcdb6aaadfa02d46695544a0 Mon Sep 17 00:00:00 2001
From: sofyalaski
Date: Mon, 4 Nov 2024 17:56:56 +0100
Subject: [PATCH 026/242] adding restrictions to deposition types
---
.../dataset-detail.component.ts | 14 +-
src/app/datasets/onedep/onedep.component.html | 66 +++----
src/app/datasets/onedep/onedep.component.ts | 184 ++++++++++--------
src/app/datasets/onedep/types/methods.enum.ts | 39 ++++
4 files changed, 185 insertions(+), 118 deletions(-)
create mode 100644 src/app/datasets/onedep/types/methods.enum.ts
diff --git a/src/app/datasets/dataset-detail/dataset-detail.component.ts b/src/app/datasets/dataset-detail/dataset-detail.component.ts
index 30f76fa82..67f706479 100644
--- a/src/app/datasets/dataset-detail/dataset-detail.component.ts
+++ b/src/app/datasets/dataset-detail/dataset-detail.component.ts
@@ -66,8 +66,7 @@ import { AttachmentService } from "shared/services/attachment.service";
standalone: false,
})
export class DatasetDetailComponent
- implements OnInit, OnDestroy, EditableComponent
-{
+ implements OnInit, OnDestroy, EditableComponent {
private subscriptions: Subscription[] = [];
private _hasUnsavedChanges = false;
form: FormGroup;
@@ -112,7 +111,7 @@ export class DatasetDetailComponent
private http: HttpClient,
private router: Router,
private fb: FormBuilder,
- ) {}
+ ) { }
ngOnInit() {
this.connectingToDepositionBackend = true;
@@ -171,7 +170,6 @@ export class DatasetDetailComponent
}
}),
);
- console.log("the keywords:" , this.dataset.keywords);
}
onEditModeEnable() {
@@ -331,7 +329,7 @@ export class DatasetDetailComponent
openAttachment(encoded: string) {
this.attachmentService.openAttachment(encoded);
}
- onEMPIARclick(){
+ onEMPIARclick() {
const id = encodeURIComponent(this.dataset.pid);
this.router.navigateByUrl("/datasets/" + id + "/empiar");
}
@@ -345,13 +343,13 @@ export class DatasetDetailComponent
DepositionBackendUrlCleaned += '/';
}
- let DepositionBackendUrlVersion = DepositionBackendUrlCleaned;
+ let DepositionBackendUrlVersion = DepositionBackendUrlCleaned + 'version';
// Try to connect to the facility backend/version to check if it is available
- console.log('Connecting to facility backend: ' + DepositionBackendUrlVersion);
+ console.log('Connecting to OneDep backend: ' + DepositionBackendUrlVersion);
this.http.get(DepositionBackendUrlVersion).subscribe(
response => {
- console.log('Connected to facility backend', response);
+ console.log('Connected to OneDep backend', response);
// If the connection is successful, store the connected facility backend URL
this.connectedDepositionBackend = DepositionBackendUrlCleaned;
this.connectingToDepositionBackend = false;
diff --git a/src/app/datasets/onedep/onedep.component.html b/src/app/datasets/onedep/onedep.component.html
index 62bf4c166..e784b686a 100644
--- a/src/app/datasets/onedep/onedep.component.html
+++ b/src/app/datasets/onedep/onedep.component.html
@@ -64,7 +64,7 @@
experimental method
-
+
{{ method.viewValue }}
@@ -151,16 +151,16 @@
Choose File
-
+
attach_file
-
-
-
Selected File: {{ selectedFile['pathToMainMap'].name }}
+
+
Selected File: {{ selectedFile['mainMap'].name }}
@@ -178,16 +178,16 @@
Choose File
-
+
attach_file
-
-
-
Selected File: {{ selectedFile['pathToHalfMap1'].name }}
+
+
Selected File: {{ selectedFile['halfMap1'].name }}
@@ -205,16 +205,16 @@
Choose File
-
+
attach_file
-
-
-
Selected File: {{ selectedFile['pathToHalfMap2'].name }}
+
+
Selected File: {{ selectedFile['halfMap2'].name }}
@@ -233,16 +233,16 @@
Choose File
-
+
attach_file
-
-
-
Selected File: {{ selectedFile['pathToHalfMask'].name }}
+
+
Selected File: {{ selectedFile['mask'].name }}
@@ -260,17 +260,17 @@
Choose File
-
+
attach_file
-
-
Selected File: {{ selectedFile['pathToAdditionalMap'].name
+
+
Selected File: {{ selectedFile['addMap'].name
}}
@@ -289,16 +289,16 @@
Choose File
-
+
attach_file
+ (change)="onFileSelected($event, 'coordinates')" style="display: none;" />
-
-
Selected File: {{ selectedFile['pathToCoordinates'].name
+
+
Selected File: {{ selectedFile['coordinates'].name
}}
@@ -317,16 +317,16 @@
Choose File
-
+
attach_file
-
-
-
Selected File: {{ selectedFile['pathToImage'].name }}
+
+
Selected File: {{ selectedFile['image'].name }}
@@ -344,16 +344,16 @@
Choose File
-
+
attach_file
-
-
-
Selected File: {{ selectedFile['pathToFSC'].name }}
+
+
Selected File: {{ selectedFile['fsc'].name }}
diff --git a/src/app/datasets/onedep/onedep.component.ts b/src/app/datasets/onedep/onedep.component.ts
index bb9f31e05..1cbb0ed07 100644
--- a/src/app/datasets/onedep/onedep.component.ts
+++ b/src/app/datasets/onedep/onedep.component.ts
@@ -14,14 +14,10 @@ import {
selectCurrentDataset,
} from "state-management/selectors/datasets.selectors";
-
+import { MethodsList, Experiment, OneDepFile } from "./types/methods.enum"
import { Subscription } from "rxjs";
import { string } from "mathjs";
-interface EmMethod {
- value: string;
- viewValue:string;
-}
@Component({
selector: 'onedep',
@@ -35,24 +31,9 @@ export class OneDepComponent implements OnInit {
form: FormGroup;
private subscriptions: Subscription[] = [];
showAssociatedMapQuestion: boolean = false;
-
- // connectedDepositionBackend: string = '';
- // connectedDepositionBackendVersion: string = '';
- // connectingToDepositionBackend: boolean = false;
- // lastUsedDepositionBackends: string[] = [];
- // forwardDepositionBackend: string = '';
- // errorMessage: string = '';
-
-
- methodsList: EmMethod[] = [
- {value:'helical', viewValue: 'Helical'},
- {value:'single-particle', viewValue:'Single Particle'},
- {value:'subtomogram-averaging',viewValue: 'Subtomogram Averaging'},
- {value:'tomogram', viewValue: 'Tomogram'},
- {value:'electron-cristallography', viewValue:'Electron Crystallography'},
- ];
-
- selectedFile: { [key: string]: File | null } = {};
+ methodsList = MethodsList;
+ experiment = Experiment;
+ selectedFile: { [key: string]: File | null } = {};
constructor(public appConfigService: AppConfigService,
@@ -61,61 +42,110 @@ export class OneDepComponent implements OnInit {
private route: ActivatedRoute,
private router: Router,
private fb: FormBuilder,
- ) { }
-
-
- ngOnInit() {
- this.store.select(selectCurrentDataset).subscribe((dataset) => {
- this.dataset = dataset;
+ ) { }
+
+
+ ngOnInit() {
+ this.store.select(selectCurrentDataset).subscribe((dataset) => {
+ this.dataset = dataset;
+ });
+ this.form = this.fb.group({
+ datasetName: this.dataset.datasetName,
+ description: this.dataset.description,
+ keywords: this.fb.array(this.dataset.keywords),
+ metadata: this.dataset.scientificMetadata,
+ emMethod: new FormControl(""),
+ deposingCoordinates: new FormControl(true),
+ associatedMap: new FormControl(false),
+ compositeMap: new FormControl(false),
+ emdbId: new FormControl(""),
+
+ mainMap: {
+ name: "",
+ type: "vo-map",
+ pathToFile: "",
+ contour: 0.0,
+ details: "",
+ },
+ halfMap1: {
+ name: "",
+ type: "half-map",
+ pathToFile: "",
+ contour: 0.0,
+ details: "",
+ },
+ halfMap2: {
+ name: "",
+ type: "half-map",
+ pathToFile: "",
+ contour: 0.0,
+ details: "",
+ },
+ mask: {
+ name: "",
+ type: "mask-map",
+ pathToFile: "",
+ contour: 0.0,
+ details: "",
+ },
+ addMap: {
+ name: "",
+ type: "add-map",
+ pathToFile: "",
+ contour: 0.0,
+ details: "",
+ },
+ coordinates: {
+ name: "",
+ type: "co-cif",
+ pathToFile: "",
+ details: "",
+ },
+ image: {
+ name: "",
+ type: "img-emdb",
+ pathToFile: "",
+ details: "",
+ },
+ // pathToCif: { --> should be extracted from this.dataset.scientificMetadata
+ // name: "",
+ // type: "undef",
+ // pathToFile: "",
+ // details: "",
+ // },
+ fsc: {
+ name: "",
+ type: "fsc-xml",
+ pathToFile: "",
+ details: "",
+ },
+ })
+ }
+
+
+ onFileSelected(event: Event, controlName: string) {
+ const input = event.target as HTMLInputElement;
+ console.log(input);
+ if (input.files && input.files.length > 0) {
+ this.selectedFile[controlName] = input.files[0];
+ this.form.get(controlName)?.setValue({
+ ...this.form.get(controlName)?.value,
+ pathToFile: this.selectedFile[controlName].name
});
- this.form = this.fb.group({
- datasetName: new FormControl("", [Validators.required]),
- description: new FormControl("", [Validators.required]),
- keywords: this.fb.array([]),
- emMethod: new FormControl(""),
- deposingCoordinates:new FormControl(true),
- associatedMap: new FormControl(false),
- compositeMap:new FormControl(false),
- emdbId:new FormControl(""),
-
- pathToMainMap: new FormControl(""),
- pathToHalfMap1: new FormControl(""),
- pathToHalfMap2: new FormControl(""),
- pathToMask: new FormControl(""),
- pathToAdditionalMap: new FormControl(""),
- pathToCoordinates: new FormControl(""),
- pathToImage: new FormControl(""),
- pathToCif: new FormControl(""),
- pathToFSC: new FormControl(""),
- })
-
- // this.connectingToDepositionBackend = true;
- // Get the GET parameter 'backendUrl' from the URL
- // this.route.queryParams.subscribe(params => {
- // const backendUrl = params['backendUrl'];
- // if (backendUrl) {
- // this.connectToDepositionBackend(backendUrl);
- // }
- // else {
- // this.connectingToDepositionBackend = false;
- // }
- // });
}
-
-
- onFileSelected(event: Event, controlName: string) {
- const input = event.target as HTMLInputElement;
- if (input.files && input.files.length > 0) {
- this.selectedFile[controlName] = input.files[0];
- this.form.get(controlName)?.setValue(this.selectedFile[controlName].name);
+ }
+ onDepositClick() {
+ const formData = this.form.value;
+ // need to properly catch the dataset details
+ console.log("creating deposition", formData)
+ this.http.post("http://localhost:8080/onedep", formData).subscribe(
+ response => {
+ console.log('created deposition in OneDep', response);
+ },
+ error => {
+ console.error('Request failed esf', error);
}
- }
- onDepositClick(){
- const formData = this.form.value;
- // need to properly catch the dataset details
- console.log(this.dataset)
- //return this.http.post(this.backendUrl, formData);
-
- }
-
+ );
+ }
+
}
diff --git a/src/app/datasets/onedep/types/methods.enum.ts b/src/app/datasets/onedep/types/methods.enum.ts
new file mode 100644
index 000000000..043208781
--- /dev/null
+++ b/src/app/datasets/onedep/types/methods.enum.ts
@@ -0,0 +1,39 @@
+export enum EmType {
+ Helical = "helical",
+ SingleParticle = "single-particle",
+ SubtomogramAveraging = "subtomogram-averaging",
+ Tomogram = "tomogram",
+ ElectronCristallography = "electron-cristallography"
+};
+interface EmMethod {
+ value: EmType;
+ viewValue:string;
+}
+
+
+export const MethodsList: EmMethod[] = [
+ {value:EmType.Helical, viewValue: 'Helical'},
+ {value:EmType.SingleParticle, viewValue:'Single Particle'},
+ {value:EmType.SubtomogramAveraging,viewValue: 'Subtomogram Averaging'},
+ {value:EmType.Tomogram, viewValue: 'Tomogram'},
+ {value:EmType.ElectronCristallography, viewValue:'Electron Crystallography'},
+ ];
+interface OneDepExperiment {
+ type: string;
+ subtype?: string;
+}
+
+export const Experiment: { [e in EmType]: OneDepExperiment } = {
+ [EmType.Helical]: { type: "em", subtype: "helical" },
+ [EmType.SingleParticle]: { type: "em", subtype: "single" },
+ [EmType.SubtomogramAveraging]: { type: "em", subtype: "subtomogram" },
+ [EmType.Tomogram]: { type: "em", subtype: "tomography" },
+ [EmType.ElectronCristallography]: { type: "ec" }
+};
+export interface OneDepFile{
+ name:File,
+ type:string,
+ pathToFile:string,
+ contour?: number,
+ details?: string,
+}
\ No newline at end of file
From 78f1fae1138b384b73e174c791d75e3fcadec6f5 Mon Sep 17 00:00:00 2001
From: sofyalaski
Date: Tue, 5 Nov 2024 10:15:39 +0100
Subject: [PATCH 027/242] refactoring
---
src/app/datasets/onedep/onedep.component.html | 64 ++++++------
src/app/datasets/onedep/onedep.component.ts | 78 +++------------
src/app/datasets/onedep/types/methods.enum.ts | 99 ++++++++++++++++---
3 files changed, 128 insertions(+), 113 deletions(-)
diff --git a/src/app/datasets/onedep/onedep.component.html b/src/app/datasets/onedep/onedep.component.html
index e784b686a..77003ab2d 100644
--- a/src/app/datasets/onedep/onedep.component.html
+++ b/src/app/datasets/onedep/onedep.component.html
@@ -151,16 +151,16 @@
Choose File
-
+
attach_file
-
-
-
Selected File: {{ selectedFile['mainMap'].name }}
+
+
Selected File: {{ selectedFile[emFile.MainMap].name }}
@@ -178,16 +178,16 @@
Choose File
-
+
attach_file
-
-
-
Selected File: {{ selectedFile['halfMap1'].name }}
+
+
Selected File: {{ selectedFile[emFile.HalfMap1].name }}
@@ -205,16 +205,16 @@
Choose File
-
+
attach_file
-
-
-
Selected File: {{ selectedFile['halfMap2'].name }}
+
+
Selected File: {{ selectedFile[emFile.HalfMap2].name }}
@@ -233,16 +233,16 @@
Choose File
-
+
attach_file
-
-
-
Selected File: {{ selectedFile['mask'].name }}
+
+
Selected File: {{ selectedFile[emFile.MaskMap].name }}
@@ -260,17 +260,17 @@
Choose File
-
+
attach_file
-
-
Selected File: {{ selectedFile['addMap'].name
+
+
Selected File: {{ selectedFile[emFile.AddMap].name
}}
@@ -289,16 +289,16 @@
Choose File
-
+
attach_file
+ (change)="onFileSelected($event, emFile.Coordinates)" style="display: none;" />
-
-
Selected File: {{ selectedFile['coordinates'].name
+
+
Selected File: {{ selectedFile[emFile.Coordinates].name
}}
@@ -317,16 +317,16 @@
Choose File
-
+
attach_file
-
-
-
Selected File: {{ selectedFile['image'].name }}
+
+
Selected File: {{ selectedFile[emFile.Image].name }}
@@ -344,16 +344,16 @@
Choose File
-
+
attach_file
-
-
-
Selected File: {{ selectedFile['fsc'].name }}
+
+
Selected File: {{ selectedFile[emFile.FSC].name }}
diff --git a/src/app/datasets/onedep/onedep.component.ts b/src/app/datasets/onedep/onedep.component.ts
index 1cbb0ed07..3d506a841 100644
--- a/src/app/datasets/onedep/onedep.component.ts
+++ b/src/app/datasets/onedep/onedep.component.ts
@@ -14,7 +14,7 @@ import {
selectCurrentDataset,
} from "state-management/selectors/datasets.selectors";
-import { MethodsList, Experiment, OneDepFile } from "./types/methods.enum"
+import { MethodsList, Experiment, EmFile, EmFiles } from "./types/methods.enum"
import { Subscription } from "rxjs";
import { string } from "mathjs";
@@ -34,7 +34,8 @@ export class OneDepComponent implements OnInit {
methodsList = MethodsList;
experiment = Experiment;
selectedFile: { [key: string]: File | null } = {};
-
+ emFile = EmFile;
+ files = EmFiles;
constructor(public appConfigService: AppConfigService,
private store: Store,
@@ -59,81 +60,24 @@ export class OneDepComponent implements OnInit {
associatedMap: new FormControl(false),
compositeMap: new FormControl(false),
emdbId: new FormControl(""),
-
- mainMap: {
- name: "",
- type: "vo-map",
- pathToFile: "",
- contour: 0.0,
- details: "",
- },
- halfMap1: {
- name: "",
- type: "half-map",
- pathToFile: "",
- contour: 0.0,
- details: "",
- },
- halfMap2: {
- name: "",
- type: "half-map",
- pathToFile: "",
- contour: 0.0,
- details: "",
- },
- mask: {
- name: "",
- type: "mask-map",
- pathToFile: "",
- contour: 0.0,
- details: "",
- },
- addMap: {
- name: "",
- type: "add-map",
- pathToFile: "",
- contour: 0.0,
- details: "",
- },
- coordinates: {
- name: "",
- type: "co-cif",
- pathToFile: "",
- details: "",
- },
- image: {
- name: "",
- type: "img-emdb",
- pathToFile: "",
- details: "",
- },
- // pathToCif: { --> should be extracted from this.dataset.scientificMetadata
- // name: "",
- // type: "undef",
- // pathToFile: "",
- // details: "",
- // },
- fsc: {
- name: "",
- type: "fsc-xml",
- pathToFile: "",
- details: "",
- },
+ // files: this.fb.group({}),
+
})
}
onFileSelected(event: Event, controlName: string) {
const input = event.target as HTMLInputElement;
- console.log(input);
+
if (input.files && input.files.length > 0) {
this.selectedFile[controlName] = input.files[0];
- this.form.get(controlName)?.setValue({
- ...this.form.get(controlName)?.value,
- pathToFile: this.selectedFile[controlName].name
- });
+ this.files[controlName].file = this.selectedFile[controlName];
+ this.files[controlName].name = this.selectedFile[controlName].name;
}
+ console.log(this.files);
}
+
+
onDepositClick() {
const formData = this.form.value;
// need to properly catch the dataset details
diff --git a/src/app/datasets/onedep/types/methods.enum.ts b/src/app/datasets/onedep/types/methods.enum.ts
index 043208781..5cefb55be 100644
--- a/src/app/datasets/onedep/types/methods.enum.ts
+++ b/src/app/datasets/onedep/types/methods.enum.ts
@@ -5,19 +5,89 @@ export enum EmType {
Tomogram = "tomogram",
ElectronCristallography = "electron-cristallography"
};
+
+export enum EmFile {
+ MainMap = 'vo-map',
+ HalfMap1 = 'half-map1',
+ HalfMap2 = 'half-map2',
+ MaskMap = 'mask-map',
+ AddMap = 'add-map',
+ Coordinates = 'co-cif',
+ Image = 'img-emdb',
+ FSC = 'fsc-xml',
+
+};
+
+
+export const EmFiles: { [f in EmFile]: OneDepFile } = {
+ [EmFile.MainMap]: {
+ name: "",
+ type: "vo-map",
+ file: null,
+ contour: 0.0,
+ details: "",
+ },
+ [EmFile.HalfMap1]: {
+ name: "",
+ type: "half-map",
+ file: null,
+ contour: 0.0,
+ details: "",
+ },
+ [EmFile.HalfMap2]: {
+ name: "",
+ type: "half-map",
+ file: null,
+ contour: 0.0,
+ details: "",
+ },
+ [EmFile.MaskMap]: {
+ name: "",
+ type: "mask-map",
+ file: null,
+ contour: 0.0,
+ details: "",
+ },
+ [EmFile.AddMap]: {
+ name: "",
+ type: "add-map",
+ file: null,
+ contour: 0.0,
+ details: "",
+ },
+ [EmFile.Coordinates]: {
+ name: "",
+ type: "co-cif",
+ file: null,
+ details: "",
+ },
+ [EmFile.Image]: {
+ name: "",
+ type: "img-emdb",
+ file: null,
+ details: "",
+ },
+ [EmFile.FSC]: {
+ name: "",
+ type: "fsc-xml",
+ file: null,
+ details: "",
+ },
+};
+
interface EmMethod {
value: EmType;
- viewValue:string;
+ viewValue: string;
}
export const MethodsList: EmMethod[] = [
- {value:EmType.Helical, viewValue: 'Helical'},
- {value:EmType.SingleParticle, viewValue:'Single Particle'},
- {value:EmType.SubtomogramAveraging,viewValue: 'Subtomogram Averaging'},
- {value:EmType.Tomogram, viewValue: 'Tomogram'},
- {value:EmType.ElectronCristallography, viewValue:'Electron Crystallography'},
- ];
+ { value: EmType.Helical, viewValue: 'Helical' },
+ { value: EmType.SingleParticle, viewValue: 'Single Particle' },
+ { value: EmType.SubtomogramAveraging, viewValue: 'Subtomogram Averaging' },
+ { value: EmType.Tomogram, viewValue: 'Tomogram' },
+ { value: EmType.ElectronCristallography, viewValue: 'Electron Crystallography' },
+];
interface OneDepExperiment {
type: string;
subtype?: string;
@@ -30,10 +100,11 @@ export const Experiment: { [e in EmType]: OneDepExperiment } = {
[EmType.Tomogram]: { type: "em", subtype: "tomography" },
[EmType.ElectronCristallography]: { type: "ec" }
};
-export interface OneDepFile{
- name:File,
- type:string,
- pathToFile:string,
- contour?: number,
- details?: string,
-}
\ No newline at end of file
+export interface OneDepFile {
+ name: string,
+ type: string,
+ file: File,
+ contour?: number,
+ details?: string,
+}
+
From a766839209c371dc7bce018240b72c4098429749 Mon Sep 17 00:00:00 2001
From: sofyalaski
Date: Tue, 5 Nov 2024 17:31:21 +0100
Subject: [PATCH 028/242] refactoring wip: experiments not passed correctly
---
src/app/datasets/onedep/onedep.component.html | 267 +++---------------
src/app/datasets/onedep/onedep.component.scss | 187 ++++++++----
src/app/datasets/onedep/onedep.component.ts | 180 ++++++++++--
src/app/datasets/onedep/types/methods.enum.ts | 8 +-
4 files changed, 330 insertions(+), 312 deletions(-)
diff --git a/src/app/datasets/onedep/onedep.component.html b/src/app/datasets/onedep/onedep.component.html
index 77003ab2d..5a8b368d5 100644
--- a/src/app/datasets/onedep/onedep.component.html
+++ b/src/app/datasets/onedep/onedep.component.html
@@ -64,7 +64,7 @@
experimental method
-
+
{{ method.viewValue }}
@@ -138,234 +138,47 @@
Choose files for deposition
-
-
-
- Main Map |
-
-
-
-
-
- Choose File
-
-
-
- attach_file
-
-
-
-
-
-
- Selected File: {{ selectedFile[emFile.MainMap].name }}
-
-
-
- |
-
-
-
- Half Map (1) |
-
-
-
-
-
- Choose File
-
-
-
- attach_file
-
-
-
-
-
-
- Selected File: {{ selectedFile[emFile.HalfMap1].name }}
-
-
-
- |
-
-
-
- Half Map (2) |
-
-
-
-
-
- Choose File
-
-
-
- attach_file
-
-
-
-
-
-
- Selected File: {{ selectedFile[emFile.HalfMap2].name }}
-
-
+
+
+ {{ fileType.header }}
+
+
+
+
+ Choose File
+
+
+ attach_file
- |
-
-
-
-
- Mask Map |
-
-
-
-
-
- Choose File
-
-
-
- attach_file
-
-
-
-
-
-
- Selected File: {{ selectedFile[emFile.MaskMap].name }}
-
-
+
+
+ Selected File: {{ selectedFile[fileType.key].name }}
- |
-
-
-
- Additional Map |
-
-
-
-
-
- Choose File
-
-
-
- attach_file
-
-
-
-
-
-
- Selected File: {{ selectedFile[emFile.AddMap].name
- }}
-
-
- |
-
-
-
-
- Coordinates |
-
-
-
-
-
- Choose File
-
-
-
- attach_file
-
-
-
-
-
-
- Selected File: {{ selectedFile[emFile.Coordinates].name
- }}
-
-
- |
-
-
-
-
- Public Image |
-
-
-
-
-
- Choose File
-
-
-
- attach_file
-
-
-
-
-
-
- Selected File: {{ selectedFile[emFile.Image].name }}
-
-
- |
-
-
-
-
- FSC-XML |
-
-
-
-
-
- Choose File
-
-
-
- attach_file
-
-
-
-
-
-
- Selected File: {{ selectedFile[emFile.FSC].name }}
-
-
- |
-
-
-
-
-
- Start Deposition
-
-
-
+
+
+
+
+
+ Contour Level
+
+
+
+
+ Details
+
+
+
+
+
+
+
+
+ Start Deposition
+
diff --git a/src/app/datasets/onedep/onedep.component.scss b/src/app/datasets/onedep/onedep.component.scss
index 71d65ed58..617a0715a 100644
--- a/src/app/datasets/onedep/onedep.component.scss
+++ b/src/app/datasets/onedep/onedep.component.scss
@@ -1,61 +1,146 @@
mat-card {
- margin: 1em;
-
- .section-icon {
- height: auto !important;
- width: auto !important;
-
- mat-icon {
- vertical-align: middle;
- }
+ margin: 1em;
+
+ .section-icon {
+ height: auto !important;
+ width: auto !important;
+
+ mat-icon {
+ vertical-align: middle;
}
-
- table {
- th {
- .questionnaire{
- min-width: 20rem;
- }
- min-width: 10rem;
- padding-right: 0.5rem;
- text-align: left;
+ }
+
+ table {
+ th {
+ .questionnaire {
+ min-width: 20rem;
}
-
- td {
- width: 100%;
- padding: 0.5rem 0;
-
- .sample-edit {
- padding-left: 0.5rem;
-
- mat-icon {
- font-size: medium;
- }
+
+ min-width: 10rem;
+ padding-right: 0.5rem;
+ text-align: left;
+ }
+
+ td {
+ width: 100%;
+ padding: 0.5rem 0;
+
+ .sample-edit {
+ padding-left: 0.5rem;
+
+ mat-icon {
+ font-size: medium;
}
-
- }
- .EMDB-ID{
- width: 15%;
- }
- .method-name{
- width: 25%;
- }
- .file-types{
- width:10%;
- }
- .full-width {
- width: 100%;
- }
- .fileChooser{
- margin-left: 0px;
}
+ }
+
+ .EMDB-ID {
+ width: 15%;
+ }
+
+ .method-name {
+ width: 25%;
+ }
+
+ .file-types {
+ width: 10%;
+ }
+
+ .full-width {
+ width: 100%;
+ }
+ }
+
+ .fileCard {
+ width: 80%;
+ margin: 10px 0 10px 0;
+ border: 1px solid #ddd;
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
+
+ mat-card-header {
+ background-color: #B3D9AC;
+ height: 26px;
+ display: flex; // Use flexbox to align items
+ align-items: center; // Center content vertically
+ padding: 0 16px; // Optional: adjust padding as needed
+ }
+ mat-card-title{
+ font-size: 16px;
+ }
+
+ .file-selection-container {
+ display: flex; // Use flexbox for layout
+ align-items: center; // Center items vertically
+ gap: 10px; // Space between items
+
+ .fileChooser {
+ background-color: #CFE7CB;
+ color: #333;
+ margin: 5px 0 0 0; // Reset any margin
+ }
.fileName {
- margin-left: 10px;
- white-space: nowrap;
- }
- .submitDep{
- background-color: blueviolet;
+ font-size: 14px; // Adjust the font size as needed
+ color: #333; // Adjust the text color if needed
}
}
+
+ mat-card-content {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+
+ .fileChooser {
+ margin: 3px auto;
+ }
+
+ .input-container {
+ display: flex; // Use flexbox for layout
+ align-items: flex-end;
+ gap: 10px; // Space between the fields
+
+ .contour-level {
+ flex: 0 0 20%; // Set to take 20% of the width
+ min-width: 100px; // Optional: set a minimum width for usability
+
+ /* Chrome, Safari, Edge, Opera */
+ input[matinput]::-webkit-outer-spin-button,
+ input[matinput]::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+ }
+
+ /* Firefox */
+ input[matinput][type=number] {
+ -moz-appearance: textfield;
+ }
+ }
+
+ .details {
+ flex: 1; // Allow this field to take the remaining space
+ min-width: 200px; // Optional: set a minimum width for usability
+ mat-form-field {
+ textarea {
+ max-height: calc(5 * 1.5em); // 5 lines max height
+ overflow-y: hidden; // Hide overflow
+ resize: none; // Disable resizing
+ line-height: 1.5; // Set line height
+
+ &:focus {
+ height: auto; // Allow height to grow as needed
+ }
+ }
+ }
+ }
+
+ mat-form-field {
+ width: 100%; // Ensure fields take full width of their flex container
+ margin-bottom: 0;
+ }
+ }
+ }
+ }
+ .submitDep {
+ background-color: #B3D9AC;
}
-
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/app/datasets/onedep/onedep.component.ts b/src/app/datasets/onedep/onedep.component.ts
index 3d506a841..ac61cf2f6 100644
--- a/src/app/datasets/onedep/onedep.component.ts
+++ b/src/app/datasets/onedep/onedep.component.ts
@@ -1,22 +1,23 @@
-import { Component, OnInit, ChangeDetectorRef } from "@angular/core";
-import { AppConfigService, HelpMessages } from "app-config.service";
+import { Component, OnInit, ViewChild, ElementRef } from "@angular/core";
+import { AppConfigService } from "app-config.service";
import { HttpClient } from '@angular/common/http';
import { ActivatedRoute, Router } from '@angular/router';
import {
FormBuilder,
FormControl,
FormGroup,
- Validators,
+ FormArray,
} from "@angular/forms";
import { Store } from "@ngrx/store";
import { Dataset } from "shared/sdk/models";
import {
-
selectCurrentDataset,
} from "state-management/selectors/datasets.selectors";
-import { MethodsList, Experiment, EmFile, EmFiles } from "./types/methods.enum"
-import { Subscription } from "rxjs";
-import { string } from "mathjs";
+import {selectCurrentUser
+} from "state-management/selectors/user.selectors";
+import { User } from "shared/sdk";
+import { MethodsList, OneDepExperiment, Experiments, EmFile, EmFiles } from "./types/methods.enum"
+import { Subscription, fromEvent } from "rxjs";
@Component({
@@ -25,17 +26,34 @@ import { string } from "mathjs";
styleUrls: ['./onedep.component.scss']
})
export class OneDepComponent implements OnInit {
+ private subscriptions: Subscription[] = [];
+ private _hasUnsavedChanges = false;
appConfig = this.appConfigService.getConfig();
dataset: Dataset | undefined;
+ user: User | undefined;
form: FormGroup;
- private subscriptions: Subscription[] = [];
showAssociatedMapQuestion: boolean = false;
methodsList = MethodsList;
- experiment = Experiment;
+ experiments = Experiments;
+ experiment: OneDepExperiment
selectedFile: { [key: string]: File | null } = {};
emFile = EmFile;
files = EmFiles;
+ detailsOverflow: string = 'hidden';
+
+ @ViewChild('fileInput') fileInput: ElementRef
| undefined;
+
+ fileTypes = [
+ { header: 'Main Map', key: this.emFile.MainMap },
+ { header: 'Half Map (1)', key: this.emFile.HalfMap1 },
+ { header: 'Half Map (2)', key: this.emFile.HalfMap2 },
+ { header: 'Mask Map', key: this.emFile.MaskMap },
+ { header: 'Additional Map', key: this.emFile.AddMap },
+ { header: 'Coordinates', key: this.emFile.Coordinates },
+ { header: 'Public Image', key: this.emFile.Image },
+ { header: 'FSC-XML', key: this.emFile.FSC },
+ ];
constructor(public appConfigService: AppConfigService,
private store: Store,
@@ -50,46 +68,148 @@ export class OneDepComponent implements OnInit {
this.store.select(selectCurrentDataset).subscribe((dataset) => {
this.dataset = dataset;
});
+ this.subscriptions.push(
+ this.store.select(selectCurrentUser).subscribe((user) => {
+ if (user) {
+ this.user = user;
+ }
+ }),
+ );
+ // Prevent user from reloading page if there are unsave changes
+ this.subscriptions.push(
+ fromEvent(window, "beforeunload").subscribe((event) => {
+ if (this.hasUnsavedChanges()) {
+ event.preventDefault();
+ }
+ }),
+ );
this.form = this.fb.group({
- datasetName: this.dataset.datasetName,
- description: this.dataset.description,
- keywords: this.fb.array(this.dataset.keywords),
metadata: this.dataset.scientificMetadata,
+ experiments: this.fb.array([]),
emMethod: new FormControl(""),
deposingCoordinates: new FormControl(true),
associatedMap: new FormControl(false),
compositeMap: new FormControl(false),
emdbId: new FormControl(""),
- // files: this.fb.group({}),
-
- })
+ files: this.fb.array([]),
+ email: this.user.email
+ })
+ }
+
+ hasUnsavedChanges() {
+ return this._hasUnsavedChanges;
+ }
+ onHasUnsavedChanges($event: boolean) {
+ this._hasUnsavedChanges = $event;
}
+ autoGrow(event: Event): void {
+ const textarea = event.target as HTMLTextAreaElement;
+ const lineHeight = parseInt(getComputedStyle(textarea).lineHeight, 10);
+ const maxLines = 5;
- onFileSelected(event: Event, controlName: string) {
- const input = event.target as HTMLInputElement;
+ // Reset height to auto to calculate scrollHeight
+ textarea.style.height = 'auto';
+
+ // Set the height based on the scrollHeight but limit it
+ const newHeight = Math.min(textarea.scrollHeight, lineHeight * maxLines);
+ textarea.style.height = `${newHeight}px`;
+ // Update overflow property based on height
+ this.detailsOverflow = textarea.scrollHeight > newHeight ? 'auto' : 'hidden';
+ }
+ onChooseFile(fileInput: HTMLInputElement): void {
+ fileInput.click();
+ }
+ onFileSelected(event: Event, controlName: EmFile) {
+ const input = event.target as HTMLInputElement;
if (input.files && input.files.length > 0) {
this.selectedFile[controlName] = input.files[0];
this.files[controlName].file = this.selectedFile[controlName];
this.files[controlName].name = this.selectedFile[controlName].name;
}
- console.log(this.files);
}
+ updateContourLevel(event: Event, controlName: EmFile) {
+ const input = (event.target as HTMLInputElement).value.trim();
+ const normalizedInput = input.replace(',', '.');
+ const parsedValue = parseFloat(normalizedInput);
+ if (!isNaN(parsedValue)) {
+ this.files[controlName].contour = parsedValue;
+ } else {
+ console.warn('Invalid number format:', input);
+ }
+ }
+ updateDetails(event: Event, controlName: EmFile) {
+ const textarea = event.target as HTMLTextAreaElement; // Cast to HTMLTextAreaElement
+ const value = textarea.value;
+ if (this.files[controlName]) {
+ this.files[controlName].details = value;
+ }
+ }
+ onDepositClick() {
+ // const filesArray = this.form.get('files') as FormArray;
+ // filesArray.clear();
+ // for (const key in this.files) {
+ // if (this.files[key].file) { // e.g coordinates or add-map might not be present
+ // filesArray.push(new FormControl(this.files[key]));
+ // }
+ // }
+
+ // const expArray = this.form.get('experiments') as FormArray;
+ // expArray.clear();
+ // expArray.push(new FormControl(this.form.get('emMethod')));
+ // const formDataToSend = {
+ // email: this.form.value.email,
+ // experiments: this.form.value.experiments,
+ // metadata: this.form.value.metadata,
+ // // emdbId: this.form.value.emdbId,
+ // files: this.form.value.files.map(file => file.file),
+ // };
+
- onDepositClick() {
- const formData = this.form.value;
- // need to properly catch the dataset details
- console.log("creating deposition", formData)
- this.http.post("http://localhost:8080/onedep", formData).subscribe(
- response => {
- console.log('created deposition in OneDep', response);
- },
- error => {
- console.error('Request failed esf', error);
+ // // const formData = this.form.value;
+ // // need to properly catch the dataset details
+ // console.log("creating deposition", formDataToSend);
+ // console.log(JSON.stringify(formDataToSend));
+
+ const filesArray = this.form.get('files') as FormArray;
+ filesArray.clear();
+ const formData = new FormData();
+
+ // Append the email
+ formData.append('email', this.form.value.email);
+
+ // Append metadata
+ formData.append('metadata', JSON.stringify(this.form.value.metadata));
+
+ // Append experiments
+
+ const experiments = this.form.value.experiments.map(exp => {
+ return {
+ type: exp.type, // adjust based on your experiment structure
+ subtype: exp.subtype // adjust based on your experiment structure
+ };
+ });
+ formData.append('experiments', JSON.stringify(experiments));
+
+ // Append files
+ for (const key in this.files) {
+ if (this.files[key].file) { // e.g coordinates or add-map might not be present
+ formData.append('files', this.files[key].file);
}
- );
- }
+ }
+
+ console.log("Creating deposition", formData);
+ console.log('Files to send:', this.files);
+ this.http.post("http://localhost:8080/onedep", formData).subscribe(
+ response => {
+ console.log('Created deposition in OneDep', response);
+ },
+ error => {
+ console.error('Request failed', error);
+ }
+);
+ }
}
diff --git a/src/app/datasets/onedep/types/methods.enum.ts b/src/app/datasets/onedep/types/methods.enum.ts
index 5cefb55be..fee023970 100644
--- a/src/app/datasets/onedep/types/methods.enum.ts
+++ b/src/app/datasets/onedep/types/methods.enum.ts
@@ -15,10 +15,8 @@ export enum EmFile {
Coordinates = 'co-cif',
Image = 'img-emdb',
FSC = 'fsc-xml',
-
};
-
export const EmFiles: { [f in EmFile]: OneDepFile } = {
[EmFile.MainMap]: {
name: "",
@@ -88,12 +86,14 @@ export const MethodsList: EmMethod[] = [
{ value: EmType.Tomogram, viewValue: 'Tomogram' },
{ value: EmType.ElectronCristallography, viewValue: 'Electron Crystallography' },
];
-interface OneDepExperiment {
+
+
+export interface OneDepExperiment {
type: string;
subtype?: string;
}
-export const Experiment: { [e in EmType]: OneDepExperiment } = {
+export const Experiments: { [e in EmType]: OneDepExperiment } = {
[EmType.Helical]: { type: "em", subtype: "helical" },
[EmType.SingleParticle]: { type: "em", subtype: "single" },
[EmType.SubtomogramAveraging]: { type: "em", subtype: "subtomogram" },
From 66acf3866f54b648d453b3261701611857cb892d Mon Sep 17 00:00:00 2001
From: sofyalaski
Date: Wed, 6 Nov 2024 17:48:42 +0100
Subject: [PATCH 029/242] pass all forms to backend, need input for orcid
---
src/app/datasets/onedep/onedep.component.html | 2 +-
src/app/datasets/onedep/onedep.component.ts | 94 ++++++-------------
2 files changed, 30 insertions(+), 66 deletions(-)
diff --git a/src/app/datasets/onedep/onedep.component.html b/src/app/datasets/onedep/onedep.component.html
index 5a8b368d5..ca292ea3a 100644
--- a/src/app/datasets/onedep/onedep.component.html
+++ b/src/app/datasets/onedep/onedep.component.html
@@ -64,7 +64,7 @@
experimental method
-
+
{{ method.viewValue }}
diff --git a/src/app/datasets/onedep/onedep.component.ts b/src/app/datasets/onedep/onedep.component.ts
index ac61cf2f6..d47c5b0f0 100644
--- a/src/app/datasets/onedep/onedep.component.ts
+++ b/src/app/datasets/onedep/onedep.component.ts
@@ -1,6 +1,6 @@
import { Component, OnInit, ViewChild, ElementRef } from "@angular/core";
import { AppConfigService } from "app-config.service";
-import { HttpClient } from '@angular/common/http';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
import { ActivatedRoute, Router } from '@angular/router';
import {
FormBuilder,
@@ -13,7 +13,8 @@ import { Dataset } from "shared/sdk/models";
import {
selectCurrentDataset,
} from "state-management/selectors/datasets.selectors";
-import {selectCurrentUser
+import {
+ selectCurrentUser
} from "state-management/selectors/user.selectors";
import { User } from "shared/sdk";
import { MethodsList, OneDepExperiment, Experiments, EmFile, EmFiles } from "./types/methods.enum"
@@ -35,7 +36,7 @@ export class OneDepComponent implements OnInit {
form: FormGroup;
showAssociatedMapQuestion: boolean = false;
methodsList = MethodsList;
- experiments = Experiments;
+ // experiments = Experiments;
experiment: OneDepExperiment
selectedFile: { [key: string]: File | null } = {};
emFile = EmFile;
@@ -91,9 +92,8 @@ export class OneDepComponent implements OnInit {
associatedMap: new FormControl(false),
compositeMap: new FormControl(false),
emdbId: new FormControl(""),
- files: this.fb.array([]),
email: this.user.email
- })
+ })
}
hasUnsavedChanges() {
@@ -147,69 +147,33 @@ export class OneDepComponent implements OnInit {
}
}
onDepositClick() {
- // const filesArray = this.form.get('files') as FormArray;
- // filesArray.clear();
- // for (const key in this.files) {
- // if (this.files[key].file) { // e.g coordinates or add-map might not be present
- // filesArray.push(new FormControl(this.files[key]));
- // }
- // }
-
- // const expArray = this.form.get('experiments') as FormArray;
- // expArray.clear();
- // expArray.push(new FormControl(this.form.get('emMethod')));
-
- // const formDataToSend = {
- // email: this.form.value.email,
- // experiments: this.form.value.experiments,
- // metadata: this.form.value.metadata,
- // // emdbId: this.form.value.emdbId,
- // files: this.form.value.files.map(file => file.file),
- // };
-
-
- // // const formData = this.form.value;
- // // need to properly catch the dataset details
- // console.log("creating deposition", formDataToSend);
- // console.log(JSON.stringify(formDataToSend));
-
- const filesArray = this.form.get('files') as FormArray;
- filesArray.clear();
- const formData = new FormData();
-
- // Append the email
- formData.append('email', this.form.value.email);
-
- // Append metadata
- formData.append('metadata', JSON.stringify(this.form.value.metadata));
-
- // Append experiments
-
- const experiments = this.form.value.experiments.map(exp => {
- return {
- type: exp.type, // adjust based on your experiment structure
- subtype: exp.subtype // adjust based on your experiment structure
- };
- });
- formData.append('experiments', JSON.stringify(experiments));
-
- // Append files
- for (const key in this.files) {
- if (this.files[key].file) { // e.g coordinates or add-map might not be present
- formData.append('files', this.files[key].file);
+ const formDataToSend = new FormData();
+ formDataToSend.append('email', this.form.value.email);
+ formDataToSend.append('metadata', JSON.stringify(this.form.value.metadata));
+ formDataToSend.append('experiments', this.form.value.emMethod);
+ // emdbId: this.form.value.emdbId,
+
+ const fileMeta = Object.entries(this.files).reduce((acc, [key, file]) => {
+ if (file.file) {
+ formDataToSend.append('file', file.file);
+ acc[file.name] = { type: file.type, contour: file.contour, details: file.details };
}
- }
+ return acc;
+ }, {});
+ formDataToSend.append('fileMetadata', JSON.stringify(fileMeta));
- console.log("Creating deposition", formData);
- console.log('Files to send:', this.files);
- this.http.post("http://localhost:8080/onedep", formData).subscribe(
- response => {
+ console.log("Creating deposition", formDataToSend);
+ this.http.post("http://localhost:8080/onedep", formDataToSend, {
+ headers: { }
+ }).subscribe(
+ response => {
console.log('Created deposition in OneDep', response);
- },
- error => {
- console.error('Request failed', error);
- }
-);
+ },
+ error => {
+ console.error('Request failed', error.error);
+ }
+ );
+
}
}
From 212fea69b3bb0945ba0f124365e6a1481345af84 Mon Sep 17 00:00:00 2001
From: sofyalaski
Date: Mon, 11 Nov 2024 15:21:05 +0100
Subject: [PATCH 030/242] wip: send data to onedep api
---
src/app/datasets/onedep/onedep.component.ts | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/src/app/datasets/onedep/onedep.component.ts b/src/app/datasets/onedep/onedep.component.ts
index d47c5b0f0..ad3e6059f 100644
--- a/src/app/datasets/onedep/onedep.component.ts
+++ b/src/app/datasets/onedep/onedep.component.ts
@@ -152,20 +152,21 @@ export class OneDepComponent implements OnInit {
formDataToSend.append('metadata', JSON.stringify(this.form.value.metadata));
formDataToSend.append('experiments', this.form.value.emMethod);
// emdbId: this.form.value.emdbId,
+ var fileMetadata = []
- const fileMeta = Object.entries(this.files).reduce((acc, [key, file]) => {
- if (file.file) {
- formDataToSend.append('file', file.file);
- acc[file.name] = { type: file.type, contour: file.contour, details: file.details };
+ for (const key in this.files) {
+ if (this.files[key].file) {
+ formDataToSend.append('file', this.files[key].file);
+ fileMetadata.push({ name: this.files[key].name, type: this.files[key].type, contour: this.files[key].contour, details: this.files[key].details });
}
- return acc;
- }, {});
- formDataToSend.append('fileMetadata', JSON.stringify(fileMeta));
+ }
+ console.log(fileMetadata);
+ formDataToSend.append('fileMetadata', JSON.stringify(fileMetadata));
console.log("Creating deposition", formDataToSend);
this.http.post("http://localhost:8080/onedep", formDataToSend, {
- headers: { }
+ headers: {}
}).subscribe(
response => {
console.log('Created deposition in OneDep', response);
From d1baed81db3b8eb861f109fffc2e53214b85adcd Mon Sep 17 00:00:00 2001
From: sofyalaski
Date: Thu, 21 Nov 2024 16:12:49 +0000
Subject: [PATCH 031/242] add contour level propagates
---
src/app/datasets/onedep/onedep.component.html | 9 +-
src/app/datasets/onedep/onedep.component.ts | 16 +-
src/assets/config.json | 164 +++++++-----------
3 files changed, 78 insertions(+), 111 deletions(-)
diff --git a/src/app/datasets/onedep/onedep.component.html b/src/app/datasets/onedep/onedep.component.html
index ca292ea3a..0d9cc8efe 100644
--- a/src/app/datasets/onedep/onedep.component.html
+++ b/src/app/datasets/onedep/onedep.component.html
@@ -160,9 +160,12 @@
Contour Level
-
diff --git a/src/app/datasets/onedep/onedep.component.ts b/src/app/datasets/onedep/onedep.component.ts
index ad3e6059f..ba92fbc1f 100644
--- a/src/app/datasets/onedep/onedep.component.ts
+++ b/src/app/datasets/onedep/onedep.component.ts
@@ -129,6 +129,20 @@ export class OneDepComponent implements OnInit {
this.files[controlName].name = this.selectedFile[controlName].name;
}
}
+ updateContourLevelMain(event: Event) {
+ const input = (event.target as HTMLInputElement).value.trim();
+ const normalizedInput = input.replace(',', '.');
+ const parsedValue = parseFloat(normalizedInput);
+ if (!isNaN(parsedValue)) {
+ [EmFile.MainMap, EmFile.HalfMap1, EmFile.HalfMap2].forEach((key) => {
+ if (this.files[key]) {
+ this.files[key].contour = parsedValue;
+ }
+ });
+ } else {
+ console.warn('Invalid number format:', input);
+ }
+ }
updateContourLevel(event: Event, controlName: EmFile) {
const input = (event.target as HTMLInputElement).value.trim();
const normalizedInput = input.replace(',', '.');
@@ -160,11 +174,9 @@ export class OneDepComponent implements OnInit {
fileMetadata.push({ name: this.files[key].name, type: this.files[key].type, contour: this.files[key].contour, details: this.files[key].details });
}
}
- console.log(fileMetadata);
formDataToSend.append('fileMetadata', JSON.stringify(fileMetadata));
- console.log("Creating deposition", formDataToSend);
this.http.post("http://localhost:8080/onedep", formDataToSend, {
headers: {}
}).subscribe(
diff --git a/src/assets/config.json b/src/assets/config.json
index 96518ad9d..a71270c0e 100644
--- a/src/assets/config.json
+++ b/src/assets/config.json
@@ -1,119 +1,79 @@
{
- "accessTokenPrefix": "Bearer ",
- "addDatasetEnabled": true,
+ "addDatasetEnabled": false,
"archiveWorkflowEnabled": false,
"datasetReduceEnabled": true,
- "datasetJsonScientificMetadata": true,
"editDatasetSampleEnabled": true,
"editMetadataEnabled": true,
- "editPublishedData": false,
- "addSampleEnabled": true,
- "externalAuthEndpoint": "/auth/msad",
- "facility": "Local",
- "siteIcon": "site-header-logo.png",
- "loginFacilityLabel": "ESS",
- "loginLdapLabel": "Ldap",
- "loginLocalLabel": "Local",
- "loginFacilityEnabled": true,
- "loginLdapEnabled": false,
- "loginLocalEnabled": true,
+ "editPublishedData": true,
+ "editSampleEnabled": true,
+ "facility": "SAMPLE-SITE",
"fileColorEnabled": true,
"fileDownloadEnabled": true,
"gettingStarted": null,
"ingestManual": null,
- "jobsEnabled": true,
+ "jobsEnabled": false,
"jsonMetadataEnabled": true,
- "jupyterHubUrl": "https://jupyterhub.esss.lu.se/",
- "landingPage": "doi.ess.eu/detail/",
+ "jupyterHubUrl": "",
+ "landingPage": "",
"lbBaseURL": "http://127.0.0.1:3000",
- "logbookEnabled": true,
- "loginFormEnabled": true,
- "maxDirectDownloadSize": 5000000000,
- "metadataPreviewEnabled": true,
- "metadataStructure": "",
- "multipleDownloadAction": "http://localhost:3012/zip",
- "multipleDownloadEnabled": true,
- "oAuth2Endpoints": [
+ "localColumns": [
{
- "authURL": "api/v3/auth/oidc",
- "displayText": "ESS One Identity"
- }
- ],
- "policiesEnabled": true,
- "retrieveDestinations": [],
- "riotBaseUrl": "http://scichat.swap.ess.eu",
- "scienceSearchEnabled": false,
- "scienceSearchUnitsEnabled": true,
- "searchPublicDataEnabled": true,
- "searchSamples": true,
- "sftpHost": "login.esss.dk",
- "shareEnabled": true,
- "shoppingCartEnabled": true,
- "shoppingCartOnHeader": true,
- "tableSciDataEnabled": true,
- "datasetDetailsShowMissingProposalId": false,
- "notificationInterceptorEnabled": true,
- "datafilesActionsEnabled": true,
- "datafilesActions": [
+ "name": "datasetName",
+ "order": 1,
+ "type": "standard",
+ "enabled": true
+ },
{
- "id": "eed8efec-4354-11ef-a3b5-d75573a5d37f",
- "order": 4,
- "label": "Download All",
- "files": "all",
- "mat_icon": "download",
- "type": "form",
- "url": "https://www.scicat.info/download/all",
- "target": "_blank",
- "enabled": "#SizeLimit",
- "authorization": ["#datasetAccess", "#datasetPublic"]
+ "name": "type",
+ "order": 2,
+ "type": "standard",
+ "enabled": true
},
{
- "id": "3072fafc-4363-11ef-b9f9-ebf568222d26",
+ "name": "creationTime",
"order": 3,
- "label": "Download Selected",
- "files": "selected",
- "mat_icon": "download",
- "type": "form",
- "url": "https://www.scicat.info/download/selected",
- "target": "_blank",
- "enabled": "#Selected && #SizeLimit",
- "authorization": ["#datasetAccess", "#datasetPublic"]
+ "type": "standard",
+ "enabled": true
},
{
- "id": "4f974f0e-4364-11ef-9c63-03d19f813f4e",
- "order": 2,
- "label": "Notebook All",
- "files": "all",
- "icon": "/assets/icons/jupyter_logo.png",
- "type": "form",
- "url": "https://www.scicat.info/notebook/all",
- "target": "_blank",
- "authorization": ["#datasetAccess", "#datasetPublic"]
+ "name": "proposalId",
+ "order": 6,
+ "type": "standard",
+ "enabled": true
},
{
- "id": "fa3ce6ee-482d-11ef-95e9-ff2c80dd50bd",
- "order": 1,
- "label": "Notebook Selected",
- "files": "selected",
- "icon": "/assets/icons/jupyter_logo.png",
- "type": "form",
- "url": "https://www.scicat.info/notebook/selected",
- "target": "_blank",
- "enabled": "#Selected",
- "authorization": ["#datasetAccess", "#datasetPublic"]
+ "name": "image",
+ "order": 7,
+ "type": "standard",
+ "enabled": true
+ },
+ {
+ "name": "sourceFolder",
+ "order": 8,
+ "type": "standard",
+ "enabled": true
}
],
- "labelMaps": {
- "filters": {
- "LocationFilter": "Location",
- "PidFilter": "Pid",
- "GroupFilter": "Group",
- "TypeFilter": "Type",
- "KeywordFilter": "Keyword",
- "DateRangeFilter": "Start Date - End Date",
- "TextFilter": "Text"
- }
- },
+ "logbookEnabled": false,
+ "loginFormEnabled": true,
+ "oAuth2Endpoints": [],
+ "maxDirectDownloadSize": 5000000000,
+ "metadataPreviewEnabled": true,
+ "metadataStructure": "tree",
+ "multipleDownloadAction": "",
+ "multipleDownloadEnabled": false,
+ "policiesEnabled": true,
+ "retrieveDestinations": [],
+ "riotBaseUrl": "",
+ "scienceSearchEnabled": true,
+ "scienceSearchUnitsEnabled": true,
+ "searchPublicDataEnabled": true,
+ "searchSamples": true,
+ "sftpHost": "",
+ "shareEnabled": false,
+ "shoppingCartEnabled": false,
+ "shoppingCartOnHeader": false,
+ "tableSciDataEnabled": true,
"defaultDatasetsListSettings": {
"columns": [
{
@@ -194,16 +154,8 @@
"type": "standard",
"enabled": false
}
- ],
- "filters": [
- { "LocationFilter": true },
- { "PidFilter": true },
- { "GroupFilter": true },
- { "TypeFilter": true },
- { "KeywordFilter": true },
- { "DateRangeFilter": true },
- { "TextFilter": true }
- ],
- "conditions": []
- }
+ ]
+ },
+ "accessTokenPrefix": "Bearer ",
+ "externalAuthEndpoint": "/api/v3/auth/ldap"
}
From 8bb84d824de46fa71da72ce3279a307aef7d3d5d Mon Sep 17 00:00:00 2001
From: sofyalaski
Date: Mon, 25 Nov 2024 16:54:21 +0000
Subject: [PATCH 032/242] add list of ORCID IDs, token not passed yet
---
src/app/datasets/datasets.module.ts | 2 +
src/app/datasets/onedep/onedep.component.html | 145 ++++++++++++++----
src/app/datasets/onedep/onedep.component.scss | 79 ++++++++--
src/app/datasets/onedep/onedep.component.ts | 21 ++-
src/app/datasets/onedep/onedep.directive.ts | 38 +++++
5 files changed, 241 insertions(+), 44 deletions(-)
create mode 100644 src/app/datasets/onedep/onedep.directive.ts
diff --git a/src/app/datasets/datasets.module.ts b/src/app/datasets/datasets.module.ts
index 8f8d905a1..2c007619c 100644
--- a/src/app/datasets/datasets.module.ts
+++ b/src/app/datasets/datasets.module.ts
@@ -91,6 +91,7 @@ import { FiltersModule } from "shared/modules/filters/filters.module";
import { userReducer } from "state-management/reducers/user.reducer";
import { MatSnackBarModule } from "@angular/material/snack-bar";
import { OneDepComponent } from "./onedep/onedep.component";
+import { OrcidFormatterDirective } from "./onedep/onedep.directive";
@NgModule({
imports: [
@@ -181,6 +182,7 @@ import { OneDepComponent } from "./onedep/onedep.component";
DatafilesActionComponent,
DatasetsFilterSettingsComponent,
OneDepComponent,
+ OrcidFormatterDirective,
],
providers: [
ArchivingService,
diff --git a/src/app/datasets/onedep/onedep.component.html b/src/app/datasets/onedep/onedep.component.html
index 0d9cc8efe..99c0aa40e 100644
--- a/src/app/datasets/onedep/onedep.component.html
+++ b/src/app/datasets/onedep/onedep.component.html
@@ -18,7 +18,8 @@
Description |
-
+
|
@@ -39,7 +40,8 @@
Keywords |
-
+
{{ keyword }}
@@ -63,8 +65,10 @@
Method
experimental method
-
-
+
+
{{ method.viewValue }}
@@ -73,28 +77,36 @@
- Are you deposing coordinates with this
+ | Are you deposing
+ coordinates with this
submission? (for PDB) |
-
-
+
+
Yes
-
+
No
|
-
+
Has an associated map been deposited to EMDB?
|
-
-
+
+
Yes
-
+
No
@@ -114,13 +126,16 @@
- Is this a composite map? |
+ Is this a composite map?
+ |
-
+
Yes
-
+
No
@@ -129,57 +144,123 @@
+
+
+
+
+
+
+ Obtain OneDep Token
+ Add instruction how to get it
+
+ Token
+
+
+
+
+
+
+ Enter 16-digit ORCID iD
+ Owners of these ORCIDs iDs are
+ allowed to access this deposition.
+
+
+
+
+
+
+
-
+
- {{ fileType.header }}
+ {{ fileType.header
+ }}
-
+
Choose File
attach_file
-
-
- Selected File: {{ selectedFile[fileType.key].name }}
+
+
+ Selected File: {{
+ selectedFile[fileType.key].name }}
-
-
+
+
Contour Level
-
+ (input)="fileType.key === 'vo-map' ? updateContourLevelMain($event) : updateContourLevel($event, fileType.key)" />
Details
-
+
-
+
Start Deposition
diff --git a/src/app/datasets/onedep/onedep.component.scss b/src/app/datasets/onedep/onedep.component.scss
index 617a0715a..ad555adaf 100644
--- a/src/app/datasets/onedep/onedep.component.scss
+++ b/src/app/datasets/onedep/onedep.component.scss
@@ -10,6 +10,62 @@ mat-card {
}
}
+ .card-container {
+ display: flex;
+ justify-content: space-between;
+ align-items: start;
+ padding: 16px;
+ }
+
+ .card-left {
+ flex: 1;
+ margin-right: 16px;
+ }
+
+ .card-right {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ /* Stack fields vertically */
+ }
+
+
+ .file-header {
+ display: flex;
+ margin-bottom: 16px;
+ }
+
+ .instruction {
+ color: #555;
+ }
+
+ .token-field {
+ width: 100%;
+ height: 20px;
+ margin-bottom: 8px;
+ margin-top: 0;
+ }
+
+ .data-field {
+ width: 30%;
+ height: 20px;
+ margin-bottom: 40px;
+ }
+
+ .add-field-btn {
+ margin-top: 16px;
+ color: rgba(0, 0, 0, 0.6);
+ transition: color 0.3s ease;
+ }
+
+ .add-field-btn:hover {
+ color: rgba(0, 0, 0, 0.9);
+ }
+
+ .add-field-btn mat-icon {
+ font-size: 24px;
+ }
+
table {
th {
.questionnaire {
@@ -64,7 +120,8 @@ mat-card {
align-items: center; // Center content vertically
padding: 0 16px; // Optional: adjust padding as needed
}
- mat-card-title{
+
+ mat-card-title {
font-size: 16px;
}
@@ -77,7 +134,8 @@ mat-card {
background-color: #CFE7CB;
color: #333;
margin: 5px 0 0 0; // Reset any margin
- }
+ }
+
.fileName {
font-size: 14px; // Adjust the font size as needed
color: #333; // Adjust the text color if needed
@@ -95,37 +153,37 @@ mat-card {
.input-container {
display: flex; // Use flexbox for layout
- align-items: flex-end;
+ align-items: flex-end;
gap: 10px; // Space between the fields
.contour-level {
flex: 0 0 20%; // Set to take 20% of the width
min-width: 100px; // Optional: set a minimum width for usability
-
+
/* Chrome, Safari, Edge, Opera */
input[matinput]::-webkit-outer-spin-button,
input[matinput]::-webkit-inner-spin-button {
- -webkit-appearance: none;
- margin: 0;
+ -webkit-appearance: none;
+ margin: 0;
}
-
+
/* Firefox */
input[matinput][type=number] {
- -moz-appearance: textfield;
+ -moz-appearance: textfield;
}
}
.details {
flex: 1; // Allow this field to take the remaining space
min-width: 200px; // Optional: set a minimum width for usability
-
+
mat-form-field {
textarea {
max-height: calc(5 * 1.5em); // 5 lines max height
overflow-y: hidden; // Hide overflow
resize: none; // Disable resizing
line-height: 1.5; // Set line height
-
+
&:focus {
height: auto; // Allow height to grow as needed
}
@@ -140,6 +198,7 @@ mat-card {
}
}
}
+
.submitDep {
background-color: #B3D9AC;
}
diff --git a/src/app/datasets/onedep/onedep.component.ts b/src/app/datasets/onedep/onedep.component.ts
index ba92fbc1f..5cea0d5a7 100644
--- a/src/app/datasets/onedep/onedep.component.ts
+++ b/src/app/datasets/onedep/onedep.component.ts
@@ -7,6 +7,7 @@ import {
FormControl,
FormGroup,
FormArray,
+ Validators,
} from "@angular/forms";
import { Store } from "@ngrx/store";
import { Dataset } from "shared/sdk/models";
@@ -43,6 +44,7 @@ export class OneDepComponent implements OnInit {
files = EmFiles;
detailsOverflow: string = 'hidden';
+
@ViewChild('fileInput') fileInput: ElementRef | undefined;
fileTypes = [
@@ -92,16 +94,31 @@ export class OneDepComponent implements OnInit {
associatedMap: new FormControl(false),
compositeMap: new FormControl(false),
emdbId: new FormControl(""),
- email: this.user.email
+ email: this.user.email,
+ jwtToken: new FormControl(""),
+ orcid: this.fb.array([]),
})
}
+ get orcidArray(): FormArray {
+ return this.form.get('orcid') as FormArray;
+ }
+
hasUnsavedChanges() {
return this._hasUnsavedChanges;
}
onHasUnsavedChanges($event: boolean) {
this._hasUnsavedChanges = $event;
}
+ addOrcidField(): void {
+ const orcidField = this.fb.group({
+ orcidId: ['', [Validators.required, Validators.pattern(/^(\d{4}-){3}\d{4}$/)]],
+ });
+ this.orcidArray.push(orcidField);
+ }
+ removeOrcidField(index: number): void {
+ this.orcidArray.removeAt(index);
+ }
autoGrow(event: Event): void {
const textarea = event.target as HTMLTextAreaElement;
@@ -163,6 +180,7 @@ export class OneDepComponent implements OnInit {
onDepositClick() {
const formDataToSend = new FormData();
formDataToSend.append('email', this.form.value.email);
+ formDataToSend.append('orcidIds', this.form.value.orcidArray);
formDataToSend.append('metadata', JSON.stringify(this.form.value.metadata));
formDataToSend.append('experiments', this.form.value.emMethod);
// emdbId: this.form.value.emdbId,
@@ -176,7 +194,6 @@ export class OneDepComponent implements OnInit {
}
formDataToSend.append('fileMetadata', JSON.stringify(fileMetadata));
-
this.http.post("http://localhost:8080/onedep", formDataToSend, {
headers: {}
}).subscribe(
diff --git a/src/app/datasets/onedep/onedep.directive.ts b/src/app/datasets/onedep/onedep.directive.ts
new file mode 100644
index 000000000..d54b0a250
--- /dev/null
+++ b/src/app/datasets/onedep/onedep.directive.ts
@@ -0,0 +1,38 @@
+import { Directive, HostListener, ElementRef, OnInit } from "@angular/core";
+
+@Directive({ selector: "[orcidFormatter]" })
+export class OrcidFormatterDirective {
+
+ private readonly maxRawLength = 16;
+
+ constructor(private el: ElementRef) {}
+
+ @HostListener('input', ['$event'])
+ onInput(event: InputEvent): void {
+ const inputElement = this.el.nativeElement as HTMLInputElement;
+
+ // Remove all existing dashes and limit to the max length
+ const rawValue = inputElement.value.replace(/-/g, '').slice(0, this.maxRawLength);
+
+ // Format with dashes
+ const formattedValue = this.formatWithDashes(rawValue);
+
+ // Update the input's visible value
+ inputElement.value = formattedValue;
+
+ // Preserve the cursor position
+ const cursorPosition = this.getAdjustedCursorPosition(rawValue, inputElement.selectionStart || 0);
+ inputElement.setSelectionRange(cursorPosition, cursorPosition);
+ }
+
+ private formatWithDashes(value: string): string {
+ return value.match(/.{1,4}/g)?.join('-') || value;
+ }
+
+ private getAdjustedCursorPosition(rawValue: string, originalPosition: number): number {
+ const rawCursorPosition = rawValue.slice(0, originalPosition).length;
+ const dashCountBeforeCursor = Math.floor(rawCursorPosition / 4);
+ return rawCursorPosition + dashCountBeforeCursor;
+ }
+
+}
\ No newline at end of file
From 0692b18ba4b28d9e9168c5d776c0b2f019430b81 Mon Sep 17 00:00:00 2001
From: sofyalaski
Date: Tue, 26 Nov 2024 14:49:47 +0000
Subject: [PATCH 033/242] wip: token and orcid entries working; need to
refactor files
---
src/app/datasets/onedep/onedep.component.html | 175 +++++++++++-------
src/app/datasets/onedep/onedep.component.scss | 21 +++
src/app/datasets/onedep/onedep.component.ts | 11 +-
3 files changed, 132 insertions(+), 75 deletions(-)
diff --git a/src/app/datasets/onedep/onedep.component.html b/src/app/datasets/onedep/onedep.component.html
index 99c0aa40e..c96828f1d 100644
--- a/src/app/datasets/onedep/onedep.component.html
+++ b/src/app/datasets/onedep/onedep.component.html
@@ -65,13 +65,19 @@
Method
experimental method
-
{{ method.viewValue }}
+
+
+ You must specify the experimental method
+
@@ -82,13 +88,17 @@
submission? (for PDB)
-
+
Yes
-
+
No
@@ -100,12 +110,16 @@
|
-
+
Yes
-
No
@@ -114,12 +128,15 @@
| |
-
+
EMDB Identifier |
EMDB ID
-
+
|
@@ -129,13 +146,17 @@
Is this a composite map?
|
-
+
Yes
-
+
No
@@ -144,7 +165,8 @@
-
+
+
+
+
+
@@ -208,55 +248,52 @@ Enter 16-digit ORCID iD
Choose files for deposition
-
-
- {{ fileType.header
- }}
-
-
-
-
- Choose File
-
-
- attach_file
-
-
-
- Selected File: {{
- selectedFile[fileType.key].name }}
+
+
+
+ {{ fileType.header }}
+
+
+
+
+ Choose File
+
+
+ attach_file
+
+
+
+ Selected File: {{ selectedFile[fileType.key].name }}
+
-
-
-
+
+
+
Date: Thu, 28 Nov 2024 11:33:59 +0000
Subject: [PATCH 034/242] wip: make calls to oneDepAPI from frontend
---
src/app/datasets/onedep/onedep.component.html | 244 +++++++++---------
src/app/datasets/onedep/onedep.component.scss | 109 ++++----
src/app/datasets/onedep/onedep.component.ts | 35 ++-
3 files changed, 209 insertions(+), 179 deletions(-)
diff --git a/src/app/datasets/onedep/onedep.component.html b/src/app/datasets/onedep/onedep.component.html
index c96828f1d..b1f021585 100644
--- a/src/app/datasets/onedep/onedep.component.html
+++ b/src/app/datasets/onedep/onedep.component.html
@@ -55,19 +55,77 @@
blur_linear
- Method Information:
+ Administrative and Method Information:
-
-
+
+
+ Obtain OneDep Token
+ Add instruction how to get it
+
+ Token
+
+
+
+
+ Enter 16-digit ORCID iD
+ Owners of these ORCIDs iDs are
+ allowed to access this deposition.
+
+
+
+
+
+
+ Enter 16-digits ORCID iD
+
+
+
+ clear
+
+
+
+
+
+
+
+ add
+
+
+
+
+
+
- Choose Electron Microscopy
- Method |
+ Choose Electron Microscopy
+ Method
experimental method
-
@@ -75,7 +133,8 @@
-
+
You must specify the experimental method
@@ -87,18 +146,14 @@
coordinates with this
submission? (for PDB)
-
-
+
Yes
-
+
No
@@ -109,17 +164,13 @@
| Has an associated map been deposited to EMDB?
|
-
-
+
Yes
-
No
@@ -128,14 +179,13 @@
-
+
EMDB Identifier |
EMDB ID
-
|
@@ -146,100 +196,28 @@
Is this a composite map?
|
-
Yes
-
+
No
|
- |
-
-
-
-
+
+ Create Deposition
+
-
-
| |