From 968ddcea6a2e4e0def804769e97516d27ec0fe9b Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Fri, 21 Jul 2023 13:44:54 -0400 Subject: [PATCH 1/5] Fixed eido projects with None tags --- pephub/routers/eido/eido.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pephub/routers/eido/eido.py b/pephub/routers/eido/eido.py index 55f815b7..9e787ab7 100644 --- a/pephub/routers/eido/eido.py +++ b/pephub/routers/eido/eido.py @@ -9,6 +9,7 @@ from starlette.requests import Request from starlette.responses import JSONResponse from typing import List, Tuple +from pepdbagent.utils import registry_path_converter from ...helpers import parse_user_file_upload, split_upload_files_on_init_file from ...dependencies import * @@ -79,9 +80,8 @@ async def validate( ) if pep_registry is not None: - # split into namespace, name, tag - namespace, name_tag = pep_registry.split("/") - name, tag = name_tag.split(":") + namespace, name, tag = registry_path_converter(pep_registry) + tag = tag or DEFAULT_TAG p = agent.project.get(namespace, name, tag) else: init_file = parse_user_file_upload(pep_files) From 747d0478be6797fb0336900c03e47381f19f4d1d Mon Sep 17 00:00:00 2001 From: Nathan LeRoy Date: Fri, 21 Jul 2023 13:52:22 -0400 Subject: [PATCH 2/5] landing tweaks --- web/src/components/layout/landing-paths.tsx | 14 +++++--------- web/src/globals.css | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/web/src/components/layout/landing-paths.tsx b/web/src/components/layout/landing-paths.tsx index 2b2e3107..98fef8f7 100644 --- a/web/src/components/layout/landing-paths.tsx +++ b/web/src/components/layout/landing-paths.tsx @@ -81,8 +81,7 @@ export const LandingPaths: FC = () => { > @@ -91,18 +90,16 @@ export const LandingPaths: FC = () => { Fork PEP - + @@ -112,8 +109,7 @@ export const LandingPaths: FC = () => { diff --git a/web/src/globals.css b/web/src/globals.css index be171a66..d70cf268 100644 --- a/web/src/globals.css +++ b/web/src/globals.css @@ -334,6 +334,20 @@ } } +.landing-icon-border { + border: 1px solid; + animation: border-glow 1s ease-in-out infinite alternate; +} + +@keyframes border-glow { + from { + border-color: #7ab9fd; + } + to { + border-color: #0d6efd; + } +} + .top-left-landing-icon { position: absolute; bottom: 332px; From c3b8b5eb8083bcf0419de4cc380c841c09f9e382 Mon Sep 17 00:00:00 2001 From: ayobi <17304717+ayobi@users.noreply.github.com> Date: Fri, 21 Jul 2023 18:13:05 -0400 Subject: [PATCH 3/5] simplified version of #20 --- pephub/routers/api/v1/namespace.py | 24 +++++++++ pephub/routers/api/v1/project.py | 82 +++++++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/pephub/routers/api/v1/namespace.py b/pephub/routers/api/v1/namespace.py index 21b61bb0..e5ca566c 100644 --- a/pephub/routers/api/v1/namespace.py +++ b/pephub/routers/api/v1/namespace.py @@ -38,6 +38,12 @@ async def get_namespace( ): """ Fetch namespace. Returns a JSON representation of the namespace. + + Don't have a namespace? + + Use the following: + + namespace: databio """ nspace = nspace.dict() nspace["projects_endpoint"] = f"{str(request.url)[:-1]}/projects" @@ -60,6 +66,12 @@ async def get_namespace_projects( ): """ Fetch the projects for a particular namespace + + Don't have a namespace? + + Use the following: + + namespace: databio """ # TODO, this API will change. Searching @@ -118,6 +130,12 @@ async def create_pep( ), agent: PEPDatabaseAgent = Depends(get_db), ): + """ + Create a PEP for a particular namespace you have write access to. + + Don't know your namespace? Log in to see. + + """ if files is not None: init_file = parse_user_file_upload(files) init_file, other_files = split_upload_files_on_init_file(files, init_file) @@ -226,6 +244,12 @@ async def upload_raw_pep( project_from_json: ProjectJsonRequest, agent: PEPDatabaseAgent = Depends(get_db), ): + """ + Upload a raw project for a particular namespace you have write access to. + + Don't know your namespace? Log in to see. + + """ try: is_private = project_from_json.is_private tag = project_from_json.tag diff --git a/pephub/routers/api/v1/project.py b/pephub/routers/api/v1/project.py index 73513572..2fb62d06 100644 --- a/pephub/routers/api/v1/project.py +++ b/pephub/routers/api/v1/project.py @@ -38,6 +38,14 @@ async def get_a_pep( ): """ Fetch a PEP from a certain namespace + + Don't have a namespace or project? + + Use the following: + + project: example + namespace: databio + """ if not isinstance(proj, peppy.Project): try: @@ -93,6 +101,13 @@ async def update_a_pep( ): """ Update a PEP from a certain namespace + + Don't have a namespace or project? + + Use the following: + + project: example + namespace: databio """ # if not logged in, they cant update if namespace not in (list_of_admins or []): @@ -255,6 +270,16 @@ async def get_pep_samples( format: Optional[str] = None, raw: Optional[bool] = False, ): + """ + Get samples from a certain project and namespace + + Don't have a namespace or project? + + Use the following: + + project: example + namespace: databio + """ if format is not None: conversion_func: Callable = SAMPLE_CONVERSION_FUNCTIONS.get(format, None) if conversion_func is not None: @@ -288,6 +313,16 @@ async def get_pep_samples( format: Optional[Literal["JSON", "String"]] = "JSON", raw: Optional[bool] = False, ): + """ + Get project configuration file from a certain project and namespace + + Don't have a namespace or project? + + Use the following: + + project: example + namespace: databio + """ if raw: proj_config = proj[CONFIG_KEY] else: @@ -303,6 +338,17 @@ async def get_pep_samples( @project.get("/samples/{sample_name}") async def get_sample(sample_name: str, proj: peppy.Project = Depends(get_project)): + """ + Get a particular sample from a certain project and namespace + + Don't have a sample name, namespace, or project? + + Use the following: + + sample_name: 4-1_11102016 + project: example + namespace: databio + """ if sample_name not in get_project_sample_names(proj): raise HTTPException(status_code=404, detail=f"sample '{sample_name}' not found") sample = proj.get_sample(sample_name) @@ -314,6 +360,16 @@ async def get_subsamples( proj: peppy.Project = Depends(get_project), download: bool = False, ): + """ + Get subsamples from a certain project and namespace + + Don't have a namespace, or project? + + Use the following: + + project: example + namespace: databio + """ subsamples = proj[SUBSAMPLE_RAW_LIST_KEY] if subsamples is not None: try: @@ -353,6 +409,14 @@ async def convert_pep( See, http://eido.databio.org/en/latest/filters/#convert-a-pep-into-an-alternative-format-with-a-filter for more information. + + Don't have a namespace, or project? + + Use the following: + + project: example + namespace: databio + """ # default to basic if filter is None: @@ -381,7 +445,17 @@ async def convert_pep( @project.get("/zip") async def zip_pep_for_download(proj: peppy.Project = Depends(get_project)): - """Zip a pep""" + """ + Zip a pep + + Don't have a namespace, or project? + + Use the following: + + project: example + namespace: databio + + """ return zip_pep(proj) @@ -396,6 +470,12 @@ async def fork_pep_to_namespace( proj_annotation: AnnotationModel = Depends(get_project_annotation), agent: PEPDatabaseAgent = Depends(get_db), ): + """ + Fork a project for a particular namespace you have write access to. + + Don't know your namespace and/project? Log in to see. + + """ fork_to = fork_request.fork_to fork_name = fork_request.fork_name fork_tag = fork_request.fork_tag From b8dc0fffe05eafb501d5d867912ed50e5c26328e Mon Sep 17 00:00:00 2001 From: Nathan LeRoy Date: Mon, 24 Jul 2023 09:31:59 -0400 Subject: [PATCH 4/5] sample table stability things --- web/src/globals.css | 8 ++++++++ web/src/pages/Home.tsx | 4 ++-- web/src/utils/sample-table.ts | 11 ++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/web/src/globals.css b/web/src/globals.css index d70cf268..403ea5e8 100644 --- a/web/src/globals.css +++ b/web/src/globals.css @@ -309,6 +309,14 @@ box-shadow: 0 0 5px #ccc inset; } +/* on mobile, remove all x-margins */ +@media screen and (max-width: 990px) { + .landing-table-container { + margin-left: 0px !important; + margin-right: 0px !important; + } +} + /* subtle glow animation */ .landing-paths { transform: translateY(-40%) translateX(-5%); diff --git a/web/src/pages/Home.tsx b/web/src/pages/Home.tsx index b73f973e..86557bd6 100644 --- a/web/src/pages/Home.tsx +++ b/web/src/pages/Home.tsx @@ -66,7 +66,7 @@ function Home() { )} - + Validation @@ -98,7 +98,7 @@ function Home() {
-
+
diff --git a/web/src/utils/sample-table.ts b/web/src/utils/sample-table.ts index 9cd413e4..357cf361 100644 --- a/web/src/utils/sample-table.ts +++ b/web/src/utils/sample-table.ts @@ -71,6 +71,14 @@ export const arraysToSampleList = (arraysList: any[][]) => { // first row is the header row let headerRow = arraysList[0]; + // look for null values, simply populate with the column name + headerRow = headerRow.map((cell, index) => { + if (!cell) { + return `column_${index + 1}`; + } + return cell; + }); + if (headerRow.every((cell) => !cell)) { toast.error('Header row cannot be empty! Please add at least one column name.'); return []; @@ -80,9 +88,6 @@ export const arraysToSampleList = (arraysList: any[][]) => { const theRest = arraysList.slice(1); const sampleList: Sample[] = []; - // restrict header row to only contain non-null values - headerRow = headerRow.filter((key) => key !== null && key !== undefined); - // if there's only a header row, return a list with one sample where all the property values are null if (arraysAreEmpty(theRest)) { const sample: Sample = {}; From 3abe123f5d08399b8669267413292a5bb3979c91 Mon Sep 17 00:00:00 2001 From: Nathan LeRoy Date: Mon, 24 Jul 2023 09:35:06 -0400 Subject: [PATCH 5/5] landing page tweaks. sample table stability --- docs/changelog.md | 7 +++++++ pephub/_version.py | 2 +- pephub/routers/api/v1/namespace.py | 4 ++-- pephub/routers/api/v1/project.py | 24 ++++++++++++------------ 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index b06f62ce..c116bcc6 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,13 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format. +## [0.9.7] - 07-24-2023 + +### Fixed + +- sample table would exhibit odd, erratic behavior if column names were left blank +- alnding page styling was not otpimal + ## [0.9.6] - 07-20-2023 ### Fixed diff --git a/pephub/_version.py b/pephub/_version.py index 50533e30..f5b77301 100644 --- a/pephub/_version.py +++ b/pephub/_version.py @@ -1 +1 @@ -__version__ = "0.9.6" +__version__ = "0.9.7" diff --git a/pephub/routers/api/v1/namespace.py b/pephub/routers/api/v1/namespace.py index e5ca566c..326e7559 100644 --- a/pephub/routers/api/v1/namespace.py +++ b/pephub/routers/api/v1/namespace.py @@ -39,7 +39,7 @@ async def get_namespace( """ Fetch namespace. Returns a JSON representation of the namespace. - Don't have a namespace? + Don't have a namespace? Use the following: @@ -67,7 +67,7 @@ async def get_namespace_projects( """ Fetch the projects for a particular namespace - Don't have a namespace? + Don't have a namespace? Use the following: diff --git a/pephub/routers/api/v1/project.py b/pephub/routers/api/v1/project.py index 2fb62d06..fe710ebe 100644 --- a/pephub/routers/api/v1/project.py +++ b/pephub/routers/api/v1/project.py @@ -39,7 +39,7 @@ async def get_a_pep( """ Fetch a PEP from a certain namespace - Don't have a namespace or project? + Don't have a namespace or project? Use the following: @@ -102,7 +102,7 @@ async def update_a_pep( """ Update a PEP from a certain namespace - Don't have a namespace or project? + Don't have a namespace or project? Use the following: @@ -273,7 +273,7 @@ async def get_pep_samples( """ Get samples from a certain project and namespace - Don't have a namespace or project? + Don't have a namespace or project? Use the following: @@ -316,7 +316,7 @@ async def get_pep_samples( """ Get project configuration file from a certain project and namespace - Don't have a namespace or project? + Don't have a namespace or project? Use the following: @@ -341,7 +341,7 @@ async def get_sample(sample_name: str, proj: peppy.Project = Depends(get_project """ Get a particular sample from a certain project and namespace - Don't have a sample name, namespace, or project? + Don't have a sample name, namespace, or project? Use the following: @@ -363,10 +363,10 @@ async def get_subsamples( """ Get subsamples from a certain project and namespace - Don't have a namespace, or project? + Don't have a namespace, or project? Use the following: - + project: example namespace: databio """ @@ -410,10 +410,10 @@ async def convert_pep( See, http://eido.databio.org/en/latest/filters/#convert-a-pep-into-an-alternative-format-with-a-filter for more information. - Don't have a namespace, or project? + Don't have a namespace, or project? Use the following: - + project: example namespace: databio @@ -448,13 +448,13 @@ async def zip_pep_for_download(proj: peppy.Project = Depends(get_project)): """ Zip a pep - Don't have a namespace, or project? + Don't have a namespace, or project? Use the following: - + project: example namespace: databio - + """ return zip_pep(proj)