Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions backend/.tes_instances
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
# Lines starting with # are comments

# ELIXIR Cloud TES Instances
Funnel/OpenPBS @ ELIXIR-CZ,https://funnel.cloud.e-infra.cz/
Funnel/Slurm @ ELIXIR-FI,https://vm4816.kaj.pouta.csc.fi/
TESK/Kubernetes @ ELIXIR-CZ (Prod),https://tesk-prod.cloud.e-infra.cz/
TESK/Kubernetes @ ELIXIR-CZ (NA),https://tesk-na.cloud.e-infra.cz/
TESK/Kubernetes @ ELIXIR-DE,https://tesk.elixir-cloud.bi.denbi.de/
TESK/Kubernetes @ ELIXIR-GR,https://tesk-eu.hypatia-comp.athenarc.gr/
TESK/OpenShift @ ELIXIR-FI,https://csc-tesk-noauth.rahtiapp.fi/
TESK North America,https://tesk-na.cloud.e-infra.cz/
Funnel/OpenPBS @ ELIXIR-CZ (Not Working),https://funnel.cloud.e-infra.cz/
Funnel/Slurm @ ELIXIR-FI (DNS resolution Failure),https://vm4816.kaj.pouta.csc.fi/
TESK/Kubernetes @ ELIXIR-CZ (Prod) (Auth Failure),https://tesk-prod.cloud.e-infra.cz/
TESK/Kubernetes @ ELIXIR-CZ (NA) (403 Forbidden),https://tesk-na.cloud.e-infra.cz/
TESK/Kubernetes @ ELIXIR-DE (DNS resolution Failure),https://tesk.elixir-cloud.bi.denbi.de/
TESK/Kubernetes @ ELIXIR-GR (Working),https://tesk-eu.hypatia-comp.athenarc.gr/
TESK/OpenShift @ ELIXIR-FI (Working),https://csc-tesk-noauth.rahtiapp.fi/
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding status annotations like "(Not Working)", "(DNS resolution Failure)", and "(Auth Failure)" directly to instance names in the configuration file is problematic. These status annotations become part of the instance name that's displayed throughout the application, which is misleading because instance health status is dynamic and should be determined at runtime, not hardcoded in configuration. Instance health is already checked dynamically by the backend health check system. Remove these status annotations and let the system determine instance health programmatically.

Suggested change
Funnel/OpenPBS @ ELIXIR-CZ (Not Working),https://funnel.cloud.e-infra.cz/
Funnel/Slurm @ ELIXIR-FI (DNS resolution Failure),https://vm4816.kaj.pouta.csc.fi/
TESK/Kubernetes @ ELIXIR-CZ (Prod) (Auth Failure),https://tesk-prod.cloud.e-infra.cz/
TESK/Kubernetes @ ELIXIR-CZ (NA) (403 Forbidden),https://tesk-na.cloud.e-infra.cz/
TESK/Kubernetes @ ELIXIR-DE (DNS resolution Failure),https://tesk.elixir-cloud.bi.denbi.de/
TESK/Kubernetes @ ELIXIR-GR (Working),https://tesk-eu.hypatia-comp.athenarc.gr/
TESK/OpenShift @ ELIXIR-FI (Working),https://csc-tesk-noauth.rahtiapp.fi/
Funnel/OpenPBS @ ELIXIR-CZ,https://funnel.cloud.e-infra.cz/
Funnel/Slurm @ ELIXIR-FI,https://vm4816.kaj.pouta.csc.fi/
TESK/Kubernetes @ ELIXIR-CZ (Prod),https://tesk-prod.cloud.e-infra.cz/
TESK/Kubernetes @ ELIXIR-CZ (NA),https://tesk-na.cloud.e-infra.cz/
TESK/Kubernetes @ ELIXIR-DE,https://tesk.elixir-cloud.bi.denbi.de/
TESK/Kubernetes @ ELIXIR-GR,https://tesk-eu.hypatia-comp.athenarc.gr/
TESK/OpenShift @ ELIXIR-FI,https://csc-tesk-noauth.rahtiapp.fi/

Copilot uses AI. Check for mistakes.

# Local Development
Local TES,http://localhost:8080
64 changes: 45 additions & 19 deletions frontend/src/pages/SubmitTask.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import styled from 'styled-components';
import { testConnection } from '../services/api';
Expand Down Expand Up @@ -201,6 +201,22 @@ const SubmitTask = () => {
refresh: refreshInstances
} = useInstances();

// Issue #8: bug: set TES Instance for Demo task to healthy instance

useEffect(() => {
if (instances.length > 0 && !formData.tes_instance) {
const elixirFiInstance = instances.find(
instance => instance.url && instance.url.includes('csc-tesk-noauth.rahtiapp.fi')
);

if (elixirFiInstance) {
setFormData(prev => ({ ...prev, tes_instance: elixirFiInstance.url }));
} else {
setFormData(prev => ({ ...prev, tes_instance: instances[0].url }));
}
}
}, [instances]);
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The useEffect hook is missing formData.tes_instance in its dependency array. React's exhaustive-deps rule requires all values used inside the effect that come from the component scope to be listed in the dependency array. Without this, the linter will warn about a missing dependency. Add formData.tes_instance to the dependency array.

Suggested change
}, [instances]);
}, [instances, formData.tes_instance]);

Copilot uses AI. Check for mistakes.

Comment on lines +212 to +225
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The useEffect hook has a problematic dependency array that includes 'formData.tes_instance'. This can cause unnecessary re-renders or potential infinite loops because the effect modifies the same state it depends on. When the effect sets formData.tes_instance, it triggers the effect again (though the condition '!formData.tes_instance' prevents the actual loop).

A better approach is to only depend on 'instances' and check the condition more carefully, or to remove formData.tes_instance from the dependency array since the effect only runs when it's empty anyway.

Suggested change
if (instances.length > 0 && !formData.tes_instance) {
const elixirFiInstance = instances.find(
instance => instance.url && instance.url.includes(ELIXIR_FI_INSTANCE_SUBSTRING)
);
if (elixirFiInstance) {
setFormData(prev => ({ ...prev, tes_instance: elixirFiInstance.url }));
} else {
setFormData(prev => ({ ...prev, tes_instance: instances[0].url }));
}
}
}, [instances, formData.tes_instance]);
if (instances.length === 0) {
return;
}
setFormData(prev => {
// If tes_instance is already set, do not override it
if (prev.tes_instance) {
return prev;
}
const elixirFiInstance = instances.find(
instance => instance.url && instance.url.includes(ELIXIR_FI_INSTANCE_SUBSTRING)
);
if (elixirFiInstance) {
return { ...prev, tes_instance: elixirFiInstance.url };
}
return { ...prev, tes_instance: instances[0].url };
});
}, [instances]);

Copilot uses AI. Check for mistakes.
const handleTestConnection = async () => {
try {
setTestingConnection(true);
Expand Down Expand Up @@ -287,15 +303,16 @@ const SubmitTask = () => {
const handleRunDemo = (demoType = 'basic') => {
const demoData = getDemoTaskData(demoType);
setFormData(demoData);
setError(null);

const taskNames = {
basic: 'Basic Hello World',
python: 'Python Script',
fileops: 'File Operations'
};
setError(null);

// Issue #9: remove demo task pop-ups upon form population
// const taskNames = {
// basic: 'Basic Hello World',
// python: 'Python Script',
// fileops: 'File Operations'
// };

alert(`${taskNames[demoType] || 'Demo'} task data loaded! Review the form and click "Submit Task" when ready.`);
// alert(`${taskNames[demoType] || 'Demo'} task data loaded! Review the form and click "Submit Task" when ready.`);
};

const handleSubmit = async (e) => {
Expand Down Expand Up @@ -330,11 +347,11 @@ const SubmitTask = () => {

console.log('Task submission result:', result);

if (result && result.message) {
alert(`Success: ${result.message}`);
} else {
alert('Task submitted successfully!');
}
// if (result && result.message) {
// alert(`Success: ${result.message}`);
// } else {
// alert('Task submitted successfully!');
// }
navigate('/tasks');
} catch (err) {
console.error('Task submission error:', err);
Expand Down Expand Up @@ -440,11 +457,20 @@ const SubmitTask = () => {
required
>
<option value="">Select TES Instance</option>
{instances.map((instance, index) => (
<option key={index} value={instance.url}>
{instance.name}
</option>
))}
{instances
.sort((a, b) => {
// Prioritize ELIXIR-Fi instance at the top
const aIsElixirFi = a.url && a.url.includes('csc-tesk-noauth.rahtiapp.fi');
const bIsElixirFi = b.url && b.url.includes('csc-tesk-noauth.rahtiapp.fi');
if (aIsElixirFi && !bIsElixirFi) return -1;
if (!aIsElixirFi && bIsElixirFi) return 1;
return 0;
})
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inline sort operation only affects the rendering of the dropdown options and does not mutate the original instances array. This means that when demo tasks are loaded via handleRunDemo (lines 303-316), the getDemoTaskData function will use instances[0].url which refers to the first instance in the unsorted array, not necessarily the Finland instance. This defeats the purpose of Issue #8, which requires demo tasks to use the Finland instance. Consider storing a reference to the Finland instance in a separate variable or refactoring getDemoTaskData to use the same instance-finding logic.

Copilot uses AI. Check for mistakes.
Comment on lines +461 to +467
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sorting function checks if 'a.url' and 'b.url' exist before calling '.includes()', which prevents errors. However, if an instance has no URL, it will be treated as non-ELIXIR-FI. Consider whether instances without URLs should be sorted differently (e.g., to the end of the list) or filtered out entirely, as they likely cannot be used for task submission anyway.

Copilot uses AI. Check for mistakes.
.map((instance, index) => (
<option key={index} value={instance.url}>
{instance.name}
</option>
))}
Comment on lines +459 to +475
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dropdown now displays unhealthy and unreachable instances alongside healthy ones. While users can see the status badges and labels, they can still select these non-functional instances. This could lead to task submission failures. Consider either:

  1. Disabling (making unselectable) unhealthy/unreachable instances in the dropdown
  2. Adding a warning when a user selects an unhealthy instance
  3. Only showing unhealthy instances as informational but preventing their selection for task submission

Copilot uses AI. Check for mistakes.
</Select>
</FormGroup>

Expand Down
4 changes: 2 additions & 2 deletions frontend/src/pages/Utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ const Utilities = () => {
));

const serviceInfo = response.data;
let successMessage = `Connection Test Successful!\n\nInstance: ${instanceName}\nResponse Time: ${responseTime}ms`;
let successMessage = `Connection Test Successful!\n\nInstance: ${instanceName}\nResponse Time: ${responseTime}ms`;

if (serviceInfo && serviceInfo.name) {
successMessage += `\nService Name: ${serviceInfo.name}`;
Expand All @@ -417,7 +417,7 @@ const Utilities = () => {

alert(successMessage);
} catch (error) {
let errorMessage = `Connection Test Failed\n\nInstance: ${instanceName}\nURL: ${url}\n\n`;
let errorMessage = `Connection Test Failed\n\nInstance: ${instanceName}\nURL: ${url}\n\n`;
let errorReason = '';
let errorCode = '';
let errorType = '';
Expand Down
Loading