diff --git a/backend/dataall/modules/omics/api/mutations.py b/backend/dataall/modules/omics/api/mutations.py
index 197dbeda7..87f7f0978 100644
--- a/backend/dataall/modules/omics/api/mutations.py
+++ b/backend/dataall/modules/omics/api/mutations.py
@@ -30,5 +30,3 @@
# ],
# resolver=delete_omics_run,
# )
-
-
diff --git a/backend/dataall/modules/omics/api/queries.py b/backend/dataall/modules/omics/api/queries.py
index 978cb1369..57f99df0d 100644
--- a/backend/dataall/modules/omics/api/queries.py
+++ b/backend/dataall/modules/omics/api/queries.py
@@ -12,7 +12,7 @@
getOmicsWorkflow = gql.QueryField(
name="getOmicsWorkflow",
- args=[gql.Argument(name="workflowId", type=gql.NonNullableType(gql.String))],
+ args=[gql.Argument(name="workflowUri", type=gql.NonNullableType(gql.String))],
type=gql.Ref("OmicsWorkflow"),
resolver=get_omics_workflow,
)
diff --git a/backend/dataall/modules/omics/api/resolvers.py b/backend/dataall/modules/omics/api/resolvers.py
index aba04b69d..4f0cdc43a 100644
--- a/backend/dataall/modules/omics/api/resolvers.py
+++ b/backend/dataall/modules/omics/api/resolvers.py
@@ -1,12 +1,13 @@
import logging
from dataall.base.api.context import Context
-from dataall.core.stacks.api import stack_helper
from dataall.base.db import exceptions
from dataall.modules.omics.services.omics_service import OmicsService
+from dataall.modules.omics.services.omics_enums import OmicsWorkflowType
from dataall.modules.omics.db.models import OmicsRun, OmicsWorkflow
log = logging.getLogger(__name__)
+
class RequestValidator:
"""Aggregates all validation logic for operating with omics"""
@staticmethod
@@ -30,6 +31,7 @@ def _required(data: dict, name: str):
if not data.get(name):
raise exceptions.RequiredParameter(name)
+
def create_omics_run(context: Context, source, input=None):
RequestValidator.validate_creation_request(input)
# request = OmicsRunCreationRequest.from_dict(input)
@@ -52,13 +54,10 @@ def list_omics_workflows(context: Context, source, filter: dict = None):
return OmicsService.list_omics_workflows(filter)
-def get_omics_workflow(context: Context, source, workflowId: str = None):
- RequestValidator.required_uri(workflowId)
- return OmicsService.get_omics_workflow(workflowId)
+def get_omics_workflow(context: Context, source, workflowUri: str = None):
+ RequestValidator.required_uri(workflowUri)
+ return OmicsService.get_omics_workflow(workflowUri)
-def run_omics_workflow(context: Context, source, workflowId: str = None, workflowType: str = 'READY2RUN', roleArn: str = None, parameters: str = None):
- RequestValidator.required_uri(workflowId)
- return OmicsService.run_omics_workflow(workflowId,workflowType,roleArn,parameters)
def delete_omics_run(context: Context, source, runUri: str = None, deleteFromAWS: bool = None):
RequestValidator.required_uri(runUri)
@@ -67,11 +66,10 @@ def delete_omics_run(context: Context, source, runUri: str = None, deleteFromAWS
delete_from_aws=deleteFromAWS
)
+
def resolve_omics_workflow(context, source: OmicsRun, **kwargs):
- return OmicsService.get_omics_workflow(source.workflowId)
+ return OmicsService.get_omics_workflow(source.workflowUri)
def resolve_omics_run_details(context, source: OmicsRun, **kwargs):
return OmicsService.get_omics_run_from_aws(source.runUri)
-
-
diff --git a/backend/dataall/modules/omics/api/types.py b/backend/dataall/modules/omics/api/types.py
index 50d38bb03..c24b3dac3 100644
--- a/backend/dataall/modules/omics/api/types.py
+++ b/backend/dataall/modules/omics/api/types.py
@@ -6,13 +6,14 @@
OmicsWorkflow = gql.ObjectType(
name="OmicsWorkflow",
fields=[
- gql.Field(name="arn", type=gql.String),
+ gql.Field(name="workflowUri", type=gql.String),
gql.Field(name="id", type=gql.String),
+ gql.Field(name="arn", type=gql.String),
gql.Field(name="name", type=gql.String),
- gql.Field(name="status", type=gql.String),
+ gql.Field(name="label", type=gql.String),
gql.Field(name="type", type=gql.String),
gql.Field(name="description", type=gql.String),
- gql.Field(name="parameterTemplate", type=gql.String), # from the omics client
+ gql.Field(name="parameterTemplate", type=gql.String),
gql.Field(name="environmentUri", type=gql.String),
],
)
@@ -29,21 +30,13 @@
],
)
-# TODO: not used at the moment
-# OmicsRunStatus = gql.ObjectType(
-# name="OmicsRunStatus",
-# fields=[
-# gql.Field(name="arn", type=gql.String),
-# gql.Field(name="id", type=gql.String),
-# gql.Field(name="status", type=gql.String),
-# gql.Field(name="runId", type=gql.String),
-# gql.Field(name="roleArn", type=gql.String),
-# gql.Field(name="statusMessage", type=gql.String),
-# gql.Field(name="creationTime", type=gql.String),
-# gql.Field(name="startTime", type=gql.String),
-# gql.Field(name="stopTime", type=gql.String),
-# ],
-# )
+OmicsRunStatus = gql.ObjectType(
+ name="OmicsRunStatus",
+ fields=[
+ gql.Field(name="status", type=gql.String),
+ gql.Field(name="statusMessage", type=gql.String)
+ ],
+)
OmicsRun = gql.ObjectType(
@@ -54,17 +47,15 @@
gql.Field("organizationUri", type=gql.String),
gql.Field("name", type=gql.String),
gql.Field("label", type=gql.String),
- gql.Field("description", type=gql.String),
- gql.Field("tags", type=gql.ArrayType(gql.String)),
gql.Field("created", type=gql.String),
gql.Field("updated", type=gql.String),
gql.Field("owner", type=gql.String),
gql.Field("AwsAccountId", type=gql.String),
gql.Field("region", type=gql.String),
- gql.Field("workflowId", type=gql.String),
+ gql.Field("workflowUri", type=gql.String),
gql.Field("SamlAdminGroupName", type=gql.String),
gql.Field("parameterTemplate", type=gql.String),
- gql.Field("outputUri", type=gql.String),
+ gql.Field("outputDatasetUri", type=gql.String),
gql.Field(
name='environment',
type=gql.Ref('Environment'),
@@ -100,5 +91,3 @@
gql.Field(name="nodes", type=gql.ArrayType(OmicsRun)),
],
)
-
-
diff --git a/backend/dataall/modules/omics/aws/omics_client.py b/backend/dataall/modules/omics/aws/omics_client.py
index a0cd661ba..138b802da 100644
--- a/backend/dataall/modules/omics/aws/omics_client.py
+++ b/backend/dataall/modules/omics/aws/omics_client.py
@@ -21,15 +21,15 @@ class OmicsClient:
def client(awsAccountId: str, region: str):
session = SessionHelper.remote_session(awsAccountId)
return session.client('omics', region_name=region)
-
+
@staticmethod
- def get_omics_workflow(id: str, session):
- workflow = OmicsRepository(session).get_workflow(id=id)
+ def get_omics_workflow(workflowUri: str, session):
+ workflow = OmicsRepository(session).get_workflow(workflowUri=workflowUri)
environment = EnvironmentRepository.get_environment_by_uri(session=session, uri=workflow.environmentUri)
client = OmicsClient.client(awsAccountId=environment.AwsAccountId, region=environment.region)
try:
response = client.get_workflow(
- id=id,
+ id=workflow.id,
type='READY2RUN'
)
return response
@@ -37,48 +37,47 @@ def get_omics_workflow(id: str, session):
logger.error(
f'Could not retrieve Ready2Run Omics Workflows status due to: {e} '
)
- return 'ERROR LISTING WORKFLOWS'
+ raise e
@staticmethod
def get_omics_run(session, runUri: str):
omics_db = OmicsRepository(session)
omics_run = omics_db.get_omics_run(runUri=runUri)
- workflow = omics_db.get_workflow(id=omics_run.workflowId)
+ workflow = omics_db.get_workflow(workflowUri=omics_run.workflowUri)
environment = EnvironmentRepository.get_environment_by_uri(session=session, uri=workflow.environmentUri)
client = OmicsClient.client(awsAccountId=environment.AwsAccountId, region=environment.region)
try:
- response = client.get_run(id=omics_run.runUri
- )
+ response = client.get_run(id=omics_run.runUri)
+ # TODO: remove prints
print(response)
return response
except ClientError as e:
logger.error(
f'Could not retrieve workflow run status due to: {e} '
)
- return 'ERROR GETTING WORKFLOW RUN'
-
+ return 'ERROR GETTING WORKFLOW RUN'
@staticmethod
def run_omics_workflow(omics_run: OmicsRun, session):
group = EnvironmentService.get_environment_group(session, omics_run.SamlAdminGroupName, omics_run.environmentUri)
+ workflow = OmicsRepository(session=session).get_workflow(workflowUri=omics_run.workflowUri)
client = OmicsClient.client(awsAccountId=omics_run.AwsAccountId, region=omics_run.region)
try:
response = client.start_run(
- workflowId=omics_run.workflowId,
- workflowType='READY2RUN',
+ workflowId=workflow.id,
+ workflowType=workflow.type,
roleArn=group.environmentIAMRoleArn,
parameters=json.loads(omics_run.parameterTemplate),
outputUri=omics_run.outputUri
)
return response
except ClientError as e:
+ # TODO: Check if we need to raise an error!
logger.error(
f'Could not retrieve workflow run status due to: {e} '
)
- return 'ERROR RUNNING OMICS WORKFLOW'
-
+ return 'ERROR RUNNING OMICS WORKFLOW'
-
@staticmethod
def list_workflows(awsAccountId, region, type) -> list:
try:
diff --git a/backend/dataall/modules/omics/cdk/omics_policy.py b/backend/dataall/modules/omics/cdk/omics_policy.py
index 8fd0d75e1..a7a8afe92 100644
--- a/backend/dataall/modules/omics/cdk/omics_policy.py
+++ b/backend/dataall/modules/omics/cdk/omics_policy.py
@@ -1,6 +1,6 @@
from aws_cdk import aws_iam as iam
-from dataall.core.environment.cdk.env_role_core_policies.service_policy import ServicePolicy
+from dataall.core.environment.cdk.env_role_core_policies.service_policy import ServicePolicy
from dataall.modules.omics.services.omics_permissions import CREATE_OMICS_RUN
@@ -15,10 +15,10 @@ def get_statements(self, group_permissions, **kwargs):
return []
return [
- iam.PolicyStatement(
- actions=[
+ iam.PolicyStatement(
+ actions=[
"omics:*"
- ],
- resources=['*'],
- ),
+ ],
+ resources=['*'],
+ ),
]
diff --git a/backend/dataall/modules/omics/db/models.py b/backend/dataall/modules/omics/db/models.py
index 726b880dd..95cb27581 100644
--- a/backend/dataall/modules/omics/db/models.py
+++ b/backend/dataall/modules/omics/db/models.py
@@ -1,37 +1,27 @@
import enum
from sqlalchemy import Column, String, ForeignKey
-from sqlalchemy.dialects.postgresql import JSON
-from sqlalchemy.orm import query_expression, relationship
from dataall.base.db import Base
from dataall.base.db import Resource, utils
-class OmicsWorkflowType(enum.Enum):
- PRIVATE = "PRIVATE"
- READY2RUN = "READY2RUN"
-
class OmicsWorkflow(Resource, Base):
__tablename__ = "omics_workflow"
+ workflowUri = Column(String, primary_key=True, default=utils.uuid("omicsWorkflowUri"))
arn = Column(String, nullable=False)
- id = Column(String, nullable=False, primary_key=True, default=utils.uuid("omicsWorkflowUri"))
- label = Column(String, nullable=False, default=utils.uuid("omicsWorkflowUri"))
- owner = Column(String, nullable=False, default=utils.uuid("omicsWorkflowUri"))
- name = Column(String, nullable=False)
- status = Column(String, nullable=False)
+ id = Column(String, nullable=False)
type = Column(String, nullable=False)
- description = Column(String, nullable=True)
- environmentUri = Column(String, nullable=False)
+ environmentUri = Column(String, nullable=True)
+
class OmicsRun(Resource, Base):
__tablename__ = "omics_run"
runUri = Column(String, nullable=False, primary_key=True, default=utils.uuid("runUri"))
organizationUri = Column(String, nullable=False)
environmentUri = Column(String, ForeignKey("environment.environmentUri", ondelete="cascade"), nullable=False)
- region = Column(String, default="eu-west-1")
- AwsAccountId = Column(String, nullable=False)
+ workflowUri = Column(String, ForeignKey("omics_workflow.workflowUri", ondelete="cascade"), nullable=False)
SamlAdminGroupName = Column(String, nullable=False)
- workflowId = Column(String, nullable=False)
parameterTemplate = Column(String, nullable=False)
outputUri = Column(String, nullable=True)
+ outputDatasetUri = Column(String, nullable=True)
diff --git a/backend/dataall/modules/omics/db/omics_repository.py b/backend/dataall/modules/omics/db/omics_repository.py
index 4d0efc37e..7ac4a47d8 100644
--- a/backend/dataall/modules/omics/db/omics_repository.py
+++ b/backend/dataall/modules/omics/db/omics_repository.py
@@ -39,10 +39,8 @@ def delete_omics_workflow(self, omics_workflow):
self._session.delete(omics_workflow)
self._session.commit()
-
- def get_workflow(self, id: str):
- return self._session.query(OmicsWorkflow).get(id)
-
+ def get_workflow(self, workflowUri: str):
+ return self._session.query(OmicsWorkflow).get(workflowUri)
def get_omics_run(self, runUri: str):
omics_run = self._session.query(OmicsRun).get(runUri)
@@ -50,7 +48,6 @@ def get_omics_run(self, runUri: str):
raise exceptions.ObjectNotFound("OmicsRun", runUri)
return omics_run
-
def _query_workflows(self, filter) -> Query:
query = self._session.query(OmicsWorkflow)
if filter and filter.get("term"):
@@ -60,17 +57,15 @@ def _query_workflows(self, filter) -> Query:
OmicsWorkflow.name.ilike(filter.get("term") + "%%"),
)
)
- print(query)
return query
-
- def paginated_omics_workflows(self,filter=None) -> dict:
+
+ def paginated_omics_workflows(self, filter=None) -> dict:
return paginate(
query=self._query_workflows(filter),
page=filter.get('page', OmicsRepository._DEFAULT_PAGE),
page_size=filter.get('pageSize', OmicsRepository._DEFAULT_PAGE_SIZE),
).to_dict()
-
def _query_user_runs(self, username, groups, filter) -> Query:
query = self._session.query(OmicsRun).filter(
or_(
@@ -87,7 +82,6 @@ def _query_user_runs(self, username, groups, filter) -> Query:
)
return query
-
def paginated_user_runs(self, username, groups, filter=None) -> dict:
return paginate(
query=self._query_user_runs(username, groups, filter),
@@ -97,7 +91,6 @@ def paginated_user_runs(self, username, groups, filter=None) -> dict:
# TODO: IMPLEMENT COUNT_RESOUCES
-
# def count_resources(self, environment, group_uri):
# return (
# self._session.query(OmicsRun)
@@ -108,4 +101,4 @@ def paginated_user_runs(self, username, groups, filter=None) -> dict:
# )
# )
# .count()
- # )
\ No newline at end of file
+ # )
diff --git a/backend/dataall/modules/omics/services/omics_enums.py b/backend/dataall/modules/omics/services/omics_enums.py
new file mode 100644
index 000000000..663b9285f
--- /dev/null
+++ b/backend/dataall/modules/omics/services/omics_enums.py
@@ -0,0 +1,6 @@
+import enum
+
+
+class OmicsWorkflowType(enum.Enum):
+ PRIVATE = "PRIVATE"
+ READY2RUN = "READY2RUN"
diff --git a/backend/dataall/modules/omics/services/omics_service.py b/backend/dataall/modules/omics/services/omics_service.py
index 0ebcb2aec..e31e57365 100644
--- a/backend/dataall/modules/omics/services/omics_service.py
+++ b/backend/dataall/modules/omics/services/omics_service.py
@@ -44,7 +44,6 @@ class OmicsRunCreationRequest:
S3OutputBucket: str = "No output bucket provided"
S3OutputPrefix: str = ""
-
@classmethod
def from_dict(cls, env):
"""Copies only required fields from the dictionary and creates an instance of class"""
@@ -86,12 +85,11 @@ def create_omics_run(*, uri: str, admin_group: str, data: dict) -> OmicsRun:
organizationUri=environment.organizationUri,
environmentUri=environment.environmentUri,
SamlAdminGroupName=admin_group,
- AwsAccountId=environment.AwsAccountId,
- region=environment.region,
- workflowId=data['workflowId'],
+ workflowUri=data['workflowUri'],
parameterTemplate=data['parameterTemplate'],
label=data['label'],
- outputUri=f"s3://{environment.resourcePrefix}-{dataset.name}-{dataset.datasetUri}"
+ outputUri=f"s3://{dataset.S3BucketName}",
+ outputDatasetUri=dataset.datasetUri
)
OmicsRepository(session).save_omics_run(omics_run)
@@ -105,14 +103,10 @@ def create_omics_run(*, uri: str, admin_group: str, data: dict) -> OmicsRun:
response = OmicsClient.run_omics_workflow(omics_run, session)
- if response:
- omics_run.runUri = response['id']
- OmicsRepository(session).save_omics_run(omics_run)
+ omics_run.runUri = response['id']
+ OmicsRepository(session).save_omics_run(omics_run)
- return True
- # TODO: in case of failure do we want to delete the object or do we want to show it in UI?
- OmicsRepository(session).delete_omics_run(omics_run)
- return False
+ return omics_run
@staticmethod
@has_resource_permission(GET_OMICS_RUN)
@@ -128,33 +122,26 @@ def get_omics_run_from_aws(uri: str):
@staticmethod
@has_tenant_permission(MANAGE_OMICS_RUNS)
- def get_omics_workflow(workflowId: str) -> dict:
- """List Omics workflows."""
+ def get_omics_workflow(uri: str) -> dict:
+ """Get Omics workflow."""
with _session() as session:
- response = OmicsClient.get_omics_workflow(id=workflowId, session=session)
+ response = OmicsClient.get_omics_workflow(workflowUri=uri, session=session)
parameterTemplateJson = json.dumps(response['parameterTemplate'])
response['parameterTemplate'] = parameterTemplateJson
+ response['workflowUri'] = uri
return response
- @staticmethod
- @has_tenant_permission(MANAGE_OMICS_RUNS)
- def run_omics_workflow(workflowId: str, workflowType: str, roleArn: str, parameters: str) -> dict:
- """List Omics workflows."""
- with _session() as session:
- response = OmicsClient.run_omics_workflow(workflowId,workflowType, roleArn, parameters, session)
- return response
-
@staticmethod
@has_tenant_permission(MANAGE_OMICS_RUNS)
def list_user_omics_runs(filter: dict) -> dict:
- """List existed user Omics pipelines. Filters only required omics_runs by the filter param"""
+ """List existed user Omics runs. Filters only required omics_runs by the filter param"""
with _session() as session:
return OmicsRepository(session).paginated_user_runs(
username=get_context().username,
groups=get_context().groups,
filter=filter
)
-
+
@staticmethod
@has_tenant_permission(MANAGE_OMICS_RUNS)
def list_omics_workflows(filter: dict) -> dict:
@@ -167,8 +154,8 @@ def list_omics_workflows(filter: dict) -> dict:
@staticmethod
@has_resource_permission(DELETE_OMICS_RUN)
def delete_omics_run(uri: str):
- ## TODO: IMPLEMENT IN omics_repository
- """Deletes Omics project from the database and if delete_from_aws is True from AWS as well"""
+ # TODO: IMPLEMENT _get_omics_run and in FRONTEND
+ """Deletes Omics run from the database and if delete_from_aws is True from AWS as well"""
with _session() as session:
omics_run = OmicsService._get_omics_run(session, uri)
if not omics_run:
@@ -181,5 +168,6 @@ def delete_omics_run(uri: str):
group=omics_run.SamlAdminGroupName,
)
+
def _session():
return get_context().db_engine.scoped_session()
diff --git a/backend/dataall/modules/omics/tasks/omics_workflows_fetcher.py b/backend/dataall/modules/omics/tasks/omics_workflows_fetcher.py
index 5880a859d..fe6beb828 100644
--- a/backend/dataall/modules/omics/tasks/omics_workflows_fetcher.py
+++ b/backend/dataall/modules/omics/tasks/omics_workflows_fetcher.py
@@ -5,7 +5,8 @@
from dataall.core.environment.db.environment_models import Environment
from dataall.base.db import get_engine
from dataall.modules.omics.aws.omics_client import OmicsClient
-from dataall.modules.omics.db.models import OmicsWorkflow, OmicsWorkflowType
+from dataall.modules.omics.db.models import OmicsWorkflow
+from dataall.modules.omics.services.omics_enums import OmicsWorkflowType
from dataall.modules.omics.db.omics_repository import OmicsRepository
@@ -18,7 +19,7 @@
def fetch_omics_workflows(engine):
"""List Omics workflows."""
- log.info(f'Starting omics workflows fetcher')
+ log.info('Starting omics workflows fetcher')
with engine.scoped_session() as session:
environments = session.query(Environment)
is_first_time = True
@@ -46,6 +47,7 @@ def fetch_omics_workflows(engine):
is_first_time = False
return True
+
if __name__ == '__main__':
ENVNAME = os.environ.get('envname', 'local')
ENGINE = get_engine(envname=ENVNAME)
diff --git a/backend/migrations/versions/9337b882dbb8_add_omics_runs.py b/backend/migrations/versions/9337b882dbb8_add_omics_runs.py
index eab83df11..fc4a9708b 100644
--- a/backend/migrations/versions/9337b882dbb8_add_omics_runs.py
+++ b/backend/migrations/versions/9337b882dbb8_add_omics_runs.py
@@ -39,5 +39,6 @@ def upgrade():
sa.PrimaryKeyConstraint('runUri', name='omics_run_pkey'),
)
+
def downgrade():
op.drop_table('omics_run')
diff --git a/frontend/src/design/components/layout/DefaultSidebar.js b/frontend/src/design/components/layout/DefaultSidebar.js
index ed064e08a..143c7379f 100644
--- a/frontend/src/design/components/layout/DefaultSidebar.js
+++ b/frontend/src/design/components/layout/DefaultSidebar.js
@@ -13,6 +13,7 @@ import { AiOutlineExperiment } from 'react-icons/ai';
import * as BiIcons from 'react-icons/bi';
import * as BsIcons from 'react-icons/bs';
import { FiCodesandbox, FiPackage } from 'react-icons/fi';
+import { FaDna } from 'react-icons/fa6';
import { MdShowChart } from 'react-icons/md';
import { SiJupyter } from 'react-icons/si';
import { VscBook } from 'react-icons/vsc';
@@ -90,7 +91,7 @@ export const DefaultSidebar = ({ openDrawer, onOpenDrawerChange }) => {
const omicsSection = {
title: 'Omics',
path: '/console/omics',
- icon: ,
+ icon: ,
active: isModuleEnabled(ModuleNames.OMICS)
};
diff --git a/frontend/src/modules/Environments/views/EnvironmentCreateForm.js b/frontend/src/modules/Environments/views/EnvironmentCreateForm.js
index cde6968ef..0a6bbf493 100644
--- a/frontend/src/modules/Environments/views/EnvironmentCreateForm.js
+++ b/frontend/src/modules/Environments/views/EnvironmentCreateForm.js
@@ -199,6 +199,10 @@ const EnvironmentCreateForm = (props) => {
{
key: 'pipelinesEnabled',
value: String(values.pipelinesEnabled)
+ },
+ {
+ key: 'omicsEnabled',
+ value: String(values.omicsEnabled)
}
]
})
@@ -506,6 +510,7 @@ const EnvironmentCreateForm = (props) => {
notebooksEnabled: isModuleEnabled(ModuleNames.NOTEBOOKS),
mlStudiosEnabled: isModuleEnabled(ModuleNames.MLSTUDIO),
pipelinesEnabled: isModuleEnabled(ModuleNames.DATAPIPELINES),
+ omicsEnabled: isModuleEnabled(ModuleNames.OMICS),
EnvironmentDefaultIAMRoleArn: '',
resourcePrefix: 'dataall',
vpcId: '',
@@ -772,6 +777,39 @@ const EnvironmentCreateForm = (props) => {
)}
+ {isModuleEnabled(ModuleNames.OMICS) && (
+
+
+
+ }
+ label={
+
+ Omics{' '}
+
+ (Requires AWS HealthOmics)
+
+
+ }
+ labelPlacement="end"
+ value={values.omicsEnabled}
+ />
+
+
+ )}
)}
diff --git a/frontend/src/modules/Omics/views/OmicsRunsList.js b/frontend/src/modules/Omics/components/OmicsRunsList.js
similarity index 100%
rename from frontend/src/modules/Omics/views/OmicsRunsList.js
rename to frontend/src/modules/Omics/components/OmicsRunsList.js
diff --git a/frontend/src/modules/Omics/components/OmicsWorkflowDetails.js b/frontend/src/modules/Omics/components/OmicsWorkflowDetails.js
index 477d0cc3a..8019bf2c2 100644
--- a/frontend/src/modules/Omics/components/OmicsWorkflowDetails.js
+++ b/frontend/src/modules/Omics/components/OmicsWorkflowDetails.js
@@ -7,7 +7,7 @@ export const OmicsWorkflowDetails = (props) => {
return (
-
+
{
/>
-
+
diff --git a/frontend/src/modules/Omics/components/OmicsWorkflowsList.js b/frontend/src/modules/Omics/components/OmicsWorkflowsList.js
new file mode 100644
index 000000000..fd9278b06
--- /dev/null
+++ b/frontend/src/modules/Omics/components/OmicsWorkflowsList.js
@@ -0,0 +1,98 @@
+import { Box, Container, Typography } from '@mui/material';
+import CircularProgress from '@mui/material/CircularProgress';
+import { useCallback, useEffect, useState } from 'react';
+import { Helmet } from 'react-helmet-async';
+import { Defaults, Pager, useSettings } from 'design';
+import { SET_ERROR, useDispatch } from 'globalErrors';
+import { useClient } from 'services';
+import { listOmicsWorkflows } from '../services';
+import { OmicsWorkflowsListItem } from './OmicsWorkflowsListItem';
+
+export const OmicsWorkflowsList = () => {
+ const dispatch = useDispatch();
+ const [items, setItems] = useState(Defaults.pagedResponse);
+ const [filter, setFilter] = useState(Defaults.filter);
+ const { settings } = useSettings();
+ // const [inputValue, setInputValue] = useState('');
+ const [loading, setLoading] = useState(true);
+ const client = useClient();
+
+ // const handleInputChange = (event) => {
+ // setInputValue(event.target.value);
+ // setFilter({ ...filter, term: event.target.value });
+ // };
+ //
+ // const handleInputKeyup = (event) => {
+ // if (event.code === 'Enter') {
+ // setFilter({ page: 1, term: event.target.value });
+ // fetchItems().catch((e) =>
+ // dispatch({ type: SET_ERROR, error: e.message })
+ // );
+ // }
+ // };
+ const handlePageChange = async (event, value) => {
+ if (value <= items.pages && value !== items.page) {
+ await setFilter({ ...filter, page: value });
+ }
+ };
+
+ const fetchItems = useCallback(async () => {
+ setLoading(true);
+ const response = await client.query(listOmicsWorkflows(filter));
+ if (!response.errors) {
+ setItems(response.data.listOmicsWorkflows);
+ } else {
+ dispatch({ type: SET_ERROR, error: response.errors[0].message });
+ }
+ setLoading(false);
+ }, [client, dispatch, filter]);
+
+ useEffect(() => {
+ if (client) {
+ fetchItems().catch((e) =>
+ dispatch({ type: SET_ERROR, error: e.message })
+ );
+ }
+ }, [client, filter.page, dispatch, fetchItems]);
+
+ if (loading) {
+ return ;
+ }
+
+ return (
+ <>
+
+ Workflows | data.all
+
+
+
+
+ {items.nodes.length <= 0 ? (
+
+ No workflows registered in data.all.
+
+ ) : (
+
+ {items.nodes.map((node) => (
+
+ ))}
+
+
+
+ )}
+
+
+
+ >
+ );
+};
diff --git a/frontend/src/modules/Omics/components/OmicsWorkflowsListItem.js b/frontend/src/modules/Omics/components/OmicsWorkflowsListItem.js
index b11dfd8c4..bf843570c 100644
--- a/frontend/src/modules/Omics/components/OmicsWorkflowsListItem.js
+++ b/frontend/src/modules/Omics/components/OmicsWorkflowsListItem.js
@@ -1,148 +1,93 @@
-// TODO: completely
-import {
- Box,
- Button,
- Card,
- Divider,
- Grid,
- Link,
- Tooltip,
- Typography
-} from '@mui/material';
-import * as FiIcons from 'react-icons/fi';
-import { Link as RouterLink } from 'react-router-dom';
+import { Box, Button, Card, Grid, Typography } from '@mui/material';
import PropTypes from 'prop-types';
-import { useNavigate } from 'react-router';
-import { FiCodesandbox } from 'react-icons/fi';
-import React from 'react';
-
-import { IconAvatar, StackStatus, useCardStyle } from 'design';
+import { useCardStyle } from 'design';
+import { Link as RouterLink } from 'react-router-dom';
-export const OmicsWorkflowsListItem = (props) => {
- const { workflow } = props;
+export const OmicsWorkflowsListItem = ({ workflow }) => {
const classes = useCardStyle();
- const navigate = useNavigate();
+
return (
-
-
-
+
+
+
+
+
+ Workflow Id
+
+
+ {`${workflow.id}`}
+
+
+
+
- } />
-
- {
- navigate(`/console/omics/workflows/${workflow.id}`);
- }}
- sx={{
- width: '99%',
- whiteSpace: 'nowrap',
- alignItems: 'left',
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- WebkitBoxOrient: 'vertical',
- WebkitLineClamp: 2
- }}
- >
-
- Workflow id: {workflow.id}
-
-
-
-
- {workflow.name}
-
-
-
+
+ Name
+
+
+ {`${workflow.name}`}
+
-
-
-
-
-
- Type
-
-
-
-
- {workflow.type}
-
-
-
-
-
-
-
-
- Status
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+ {`${workflow.type}`}
+
-
-
-
+
+
+
+
+
+
);
};
OmicsWorkflowsListItem.propTypes = {
diff --git a/frontend/src/modules/Omics/components/index.js b/frontend/src/modules/Omics/components/index.js
index be02a0c9d..3464f4436 100644
--- a/frontend/src/modules/Omics/components/index.js
+++ b/frontend/src/modules/Omics/components/index.js
@@ -1,2 +1,4 @@
-export * from './OmicsWorkflowsListItem';
+export * from './OmicsRunsList';
export * from './OmicsWorkflowDetails';
+export * from './OmicsWorkflowsList';
+export * from './OmicsWorkflowsListItem';
diff --git a/frontend/src/modules/Omics/services/getOmicsWorkflow.js b/frontend/src/modules/Omics/services/getOmicsWorkflow.js
index 922948cfb..f73f24c94 100644
--- a/frontend/src/modules/Omics/services/getOmicsWorkflow.js
+++ b/frontend/src/modules/Omics/services/getOmicsWorkflow.js
@@ -1,17 +1,17 @@
import { gql } from 'apollo-boost';
// TODO: add output fields
-export const getOmicsWorkflow = (workflowId) => ({
+export const getOmicsWorkflow = (workflowUri) => ({
variables: {
- workflowId
+ workflowUri
},
query: gql`
- query getOmicsWorkflow($workflowId: String!) {
- getOmicsWorkflow(workflowId: $workflowId) {
+ query getOmicsWorkflow($workflowUri: String!) {
+ getOmicsWorkflow(workflowUri: $workflowUri) {
+ workflowUri
id
name
description
parameterTemplate
- status
type
}
}
diff --git a/frontend/src/modules/Omics/services/listOmicsRuns.js b/frontend/src/modules/Omics/services/listOmicsRuns.js
index 45fdb6c40..919ea9bd4 100644
--- a/frontend/src/modules/Omics/services/listOmicsRuns.js
+++ b/frontend/src/modules/Omics/services/listOmicsRuns.js
@@ -14,11 +14,11 @@ export const listOmicsRuns = (filter) => ({
hasPrevious
nodes {
runUri
- workflowId
+ workflowUri
name
owner
SamlAdminGroupName
- outputUri
+ outputDatasetUri
description
label
created
@@ -37,23 +37,17 @@ export const listOmicsRuns = (filter) => ({
organizationUri
}
workflow {
- id
+ label
name
+ workflowUri
+ id
description
parameterTemplate
- status
type
}
status {
- arn
- id
status
- runId
- roleArn
statusMessage
- creationTime
- startTime
- stopTime
}
}
}
diff --git a/frontend/src/modules/Omics/services/listOmicsWorkflows.js b/frontend/src/modules/Omics/services/listOmicsWorkflows.js
index a6deb77ff..695586317 100644
--- a/frontend/src/modules/Omics/services/listOmicsWorkflows.js
+++ b/frontend/src/modules/Omics/services/listOmicsWorkflows.js
@@ -15,10 +15,11 @@ export const listOmicsWorkflows = (filter) => ({
hasPrevious
nodes {
arn
- name
id
+ name
+ label
+ workflowUri
description
- status
type
parameterTemplate
}
diff --git a/frontend/src/modules/Omics/views/OmicsList.js b/frontend/src/modules/Omics/views/OmicsList.js
new file mode 100644
index 000000000..a5095b821
--- /dev/null
+++ b/frontend/src/modules/Omics/views/OmicsList.js
@@ -0,0 +1,81 @@
+import React, { useState } from 'react';
+import { Helmet } from 'react-helmet-async';
+import {
+ Box,
+ Container,
+ Divider,
+ Grid,
+ Tab,
+ Tabs,
+ Typography
+} from '@mui/material';
+import { FaDna, FaGear } from 'react-icons/fa6';
+import { useSettings } from 'design';
+
+import { OmicsWorkflowsList, OmicsRunList } from '../components';
+
+const tabs = [
+ { label: 'Workflows', value: 'workflows', icon: },
+ { label: 'Runs', value: 'runs', icon: }
+];
+
+const OmicsList = () => {
+ const { settings } = useSettings();
+ const [currentTab, setCurrentTab] = useState('workflows');
+
+ const handleTabsChange = (event, value) => {
+ setCurrentTab(value);
+ };
+
+ return (
+ <>
+
+ Omics | data.all
+
+
+
+
+
+
+ Omics
+
+
+
+
+
+ {tabs.map((tab) => (
+
+ ))}
+
+
+
+
+ {currentTab === 'workflows' && }
+ {currentTab === 'runs' && }
+
+
+
+ >
+ );
+};
+
+export default OmicsList;
diff --git a/frontend/src/modules/Omics/views/OmicsListView.js b/frontend/src/modules/Omics/views/OmicsListView.js
deleted file mode 100644
index f2f121f18..000000000
--- a/frontend/src/modules/Omics/views/OmicsListView.js
+++ /dev/null
@@ -1,68 +0,0 @@
-import React, { useState } from 'react';
-import { Helmet } from 'react-helmet-async';
-import { Box, Container, Divider, Tab, Tabs } from '@mui/material';
-import { FaAws } from 'react-icons/fa';
-import { Info } from '@mui/icons-material';
-import { useSettings } from 'design';
-
-import { OmicsRunList } from './OmicsRunsList';
-import { OmicsWorkflowsList } from './OmicsWorkflowsList';
-//TODO: mostly done, but review
-const tabs = [
- { label: 'Workflows', value: 'workflows', icon: },
- { label: 'Runs', value: 'runs', icon: }
-];
-
-const OmicsView = () => {
- const { settings } = useSettings();
- const [currentTab, setCurrentTab] = useState('workflows');
-
- const handleTabsChange = (event, value) => {
- setCurrentTab(value);
- };
-
- return (
- <>
-
- Omics
-
-
-
- {tabs.map((tab) => (
-
- ))}
-
-
-
-
-
-
- {currentTab === 'workflows' && }
- {currentTab === 'runs' && }
-
-
-
- >
- );
-};
-
-export default OmicsView;
diff --git a/frontend/src/modules/Omics/views/OmicsRunCreateForm.js b/frontend/src/modules/Omics/views/OmicsRunCreateForm.js
index 74415c46c..d45c2c472 100644
--- a/frontend/src/modules/Omics/views/OmicsRunCreateForm.js
+++ b/frontend/src/modules/Omics/views/OmicsRunCreateForm.js
@@ -48,7 +48,7 @@ const OmicsRunCreateForm = (props) => {
const [loading, setLoading] = useState(true);
const fetchItem = useCallback(async () => {
setLoading(true);
- const response = await client.query(getOmicsWorkflow(params.workflowId));
+ const response = await client.query(getOmicsWorkflow(params.uri));
if (!response.errors) {
setOmicsWorkflow(response.data.getOmicsWorkflow);
console.log(omicsWorkflow); // eslint-disable-line no-console
@@ -59,7 +59,7 @@ const OmicsRunCreateForm = (props) => {
dispatch({ type: SET_ERROR, error });
}
setLoading(false);
- }, [client, dispatch, params.workflowId]);
+ }, [client, dispatch, params.uri]);
const [groupOptions, setGroupOptions] = useState([]);
const [environmentOptions, setEnvironmentOptions] = useState([]);
@@ -155,7 +155,7 @@ const OmicsRunCreateForm = (props) => {
createOmicsRun({
label: values.label,
environmentUri: values.environment.environmentUri,
- workflowId: params.workflowId,
+ workflowUri: omicsWorkflow.workflowUri,
parameterTemplate: values.parameterTemplate,
SamlAdminGroupName: values.SamlAdminGroupName,
destination: values.destination
@@ -255,7 +255,7 @@ const OmicsRunCreateForm = (props) => {
{
parameterTemplate: omicsWorkflow.parameterTemplate
}}
validationSchema={Yup.object().shape({
- omicsWorkflowId: Yup.string()
+ workflowUri: Yup.string()
.max(255)
.required('*Workflow is required'),
label: Yup.string().max(255).required('*Run Name is required'),
@@ -302,17 +302,11 @@ const OmicsRunCreateForm = (props) => {
diff --git a/frontend/src/modules/Omics/views/OmicsWorkflowParameters.js b/frontend/src/modules/Omics/views/OmicsWorkflowParameters.js
deleted file mode 100644
index aa7a8f52e..000000000
--- a/frontend/src/modules/Omics/views/OmicsWorkflowParameters.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import { Box, Grid } from '@mui/material';
-import PropTypes from 'prop-types';
-import { ObjectBrief, ObjectMetadata } from 'design';
-
-const OmicsWorkflowDetails = (props) => {
- const { workflow, ...other } = props;
-
- return (
-
-
-
- 0 ? workflow.tags : ['-']
- }
- />
-
-
-
-
-
-
- );
-};
-
-OmicsWorkflowDetails.propTypes = {
- workflow: PropTypes.object.isRequired
-};
-
-export default OmicsWorkflowDetails;
diff --git a/frontend/src/modules/Omics/views/OmicsWorkflowView.js b/frontend/src/modules/Omics/views/OmicsWorkflowView.js
index 6f54bb09e..07cfeb353 100644
--- a/frontend/src/modules/Omics/views/OmicsWorkflowView.js
+++ b/frontend/src/modules/Omics/views/OmicsWorkflowView.js
@@ -33,7 +33,7 @@ const OmicsWorkflowView = () => {
} else {
const error = response.errors
? response.errors[0].message
- : 'Omics Workflownot found';
+ : 'Omics Workflow not found';
dispatch({ type: SET_ERROR, error });
}
setLoading(false);
@@ -65,26 +65,29 @@ const OmicsWorkflowView = () => {
}}
>
-
-
+
+
- Omics Workflow: {omicsWorkflow.name}
+ Omics Workflow
+
+
+ {omicsWorkflow.name}
-
-
-
- }
- sx={{ m: 1 }}
- to={`/console/omics/runs/new/${omicsWorkflow.id}`}
- variant="contained"
- >
- Create Run
-
-
+
+
+ }
+ sx={{ m: 1 }}
+ to={`/console/omics/workflows/${omicsWorkflow.workflowUri}/runs/new/`}
+ variant="contained"
+ >
+ Create Run
+
+
+
diff --git a/frontend/src/modules/Omics/views/OmicsWorkflowsList.js b/frontend/src/modules/Omics/views/OmicsWorkflowsList.js
deleted file mode 100644
index e9ec1fa46..000000000
--- a/frontend/src/modules/Omics/views/OmicsWorkflowsList.js
+++ /dev/null
@@ -1,155 +0,0 @@
-import { useCallback, useEffect, useState } from 'react';
-import { Link as RouterLink } from 'react-router-dom';
-import {
- Box,
- Breadcrumbs,
- Container,
- Grid,
- Link,
- Typography
-} from '@mui/material';
-import CircularProgress from '@mui/material/CircularProgress';
-import { Helmet } from 'react-helmet-async';
-
-import { useClient } from 'services';
-import {
- ChevronRightIcon,
- Defaults,
- Pager,
- SearchInput,
- useSettings
-} from 'design';
-import { SET_ERROR, useDispatch } from 'globalErrors';
-import { listOmicsWorkflows } from '../services';
-import { OmicsWorkflowsListItem } from '../components';
-
-function OmicsPageHeader() {
- return (
-
-
-
- Workflows
-
- }
- sx={{ mt: 1 }}
- >
-
- Play
-
-
- Workflows
-
-
-
-
- );
-}
-
-export const OmicsWorkflowsList = () => {
- const dispatch = useDispatch();
- const [items, setItems] = useState(Defaults.pagedResponse);
- const [filter, setFilter] = useState(Defaults.filter);
- const { settings } = useSettings();
- const [inputValue, setInputValue] = useState('');
- const [loading, setLoading] = useState(true);
- const client = useClient();
-
- const fetchItems = useCallback(async () => {
- setLoading(true);
- const response = await client.query(listOmicsWorkflows(filter));
- if (!response.errors) {
- setItems(response.data.listOmicsWorkflows);
- } else {
- dispatch({ type: SET_ERROR, error: response.errors[0].message });
- }
- setLoading(false);
- }, [client, dispatch, filter]);
-
- const handleInputChange = (event) => {
- setInputValue(event.target.value);
- setFilter({ ...filter, term: event.target.value });
- };
-
- const handleInputKeyup = (event) => {
- if (event.code === 'Enter') {
- setFilter({ page: 1, term: event.target.value });
- fetchItems().catch((e) =>
- dispatch({ type: SET_ERROR, error: e.message })
- );
- }
- };
-
- const handlePageChange = async (event, value) => {
- if (value <= items.pages && value !== items.page) {
- await setFilter({ ...filter, page: value });
- }
- };
-
- useEffect(() => {
- if (client) {
- fetchItems().catch((e) =>
- dispatch({ type: SET_ERROR, error: e.message })
- );
- }
- }, [client, filter.page, dispatch, fetchItems]);
-
- return (
- <>
-
- Workflows | data.all
-
-
-
-
-
-
-
-
-
- {loading ? (
-
- ) : (
-
-
- {items.nodes.map((node) => (
-
- ))}
-
-
-
-
- )}
-
-
-
- >
- );
-};
diff --git a/frontend/src/modules/index.js b/frontend/src/modules/index.js
index 873e5177d..5599e9abd 100644
--- a/frontend/src/modules/index.js
+++ b/frontend/src/modules/index.js
@@ -5,6 +5,7 @@ export * from './Glossaries';
export * from './MLStudio';
export * from './Notebooks';
export * from './Notifications';
+export * from './Omics';
export * from './Pipelines';
export * from './Shares';
export * from './Worksheets';
diff --git a/frontend/src/routes.js b/frontend/src/routes.js
index 8852233b7..db9fb8ad3 100644
--- a/frontend/src/routes.js
+++ b/frontend/src/routes.js
@@ -154,17 +154,13 @@ const GlossaryCreateForm = Loadable(
);
const OmicsList = Loadable(
- lazy(() => import('./modules/Omics/views/OmicsListView'))
+ lazy(() => import('./modules/Omics/views/OmicsList'))
);
-const OmicsWorkflowsList = Loadable(
- lazy(() => import('./modules/Omics/views/OmicsWorkflowsList'))
-);
-const OmicsWorkflowsView = Loadable(
+
+const OmicsWorkflowView = Loadable(
lazy(() => import('./modules/Omics/views/OmicsWorkflowView'))
);
-const OmicsRunsList = Loadable(
- lazy(() => import('./modules/Omics/views/OmicsRunsList'))
-);
+
const OmicsRunCreateForm = Loadable(
lazy(() => import('./modules/Omics/views/OmicsRunCreateForm'))
);
@@ -416,20 +412,12 @@ const routes = [
path: 'omics',
element:
},
- {
- path: 'omics/workflows',
- element:
- },
- {
- path: 'omics/runs',
- element:
- },
{
path: 'omics/workflows/:uri',
- element:
+ element:
},
{
- path: 'omics/runs/new/:workflowId',
+ path: 'omics/workflows/:uri/runs/new',
element:
}
]