Skip to content

Commit

Permalink
Merge pull request #263 from helxplatform/feature/dug-0.9-ui
Browse files Browse the repository at this point in the history
Feature/dug 0.9 UI
  • Loading branch information
frostyfan109 authored Jul 21, 2023
2 parents 86f1867 + c92a2b7 commit 181b300
Show file tree
Hide file tree
Showing 22 changed files with 364 additions and 180 deletions.
4 changes: 2 additions & 2 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ REACT_APP_WORKSPACES_ENABLED=false
# Enable when working with Dug
REACT_APP_SEMANTIC_SEARCH_ENABLED='true'
# Points the app to the Dug API
REACT_APP_HELX_SEARCH_URL='https:\/\/heal-dev.apps.renci.org'
REACT_APP_HELX_SEARCH_URL='https:\/\/heal-dev.apps.renci.org\/search-api'
# Only necessary if working with analytics specifically.
# Should be a project token/GA property. Make sure to configure details
# in env.json
Expand All @@ -19,4 +19,4 @@ REACT_APP_HIDDEN_RESULT_TABS=''
# Some static assets such as app logo are loaded externally from the dockstore repository (helx-apps).
REACT_APP_DOCKSTORE_BRANCH=master
# Some static assets such as brand logo are loaded externally from the Appstore repository.
REACT_APP_APPSTORE_ASSET_BRANCH=master
REACT_APP_APPSTORE_ASSET_BRANCH=master
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ RUN npm run build
FROM nginx:latest
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /usr/src/app/build/ /usr/share/nginx/static/
RUN mv /usr/share/nginx/static/frontend/index.html /usr/share/nginx/html/
# RUN mv /usr/share/nginx/static/frontend/index.html /usr/share/nginx/html/

WORKDIR /usr/src/app
COPY bin /usr/src/app/bin
Expand Down
15 changes: 15 additions & 0 deletions bin/create_index
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash

if [ -z "$1" ]
then
echo "Usage: create_index /path/to/build"
exit 1
fi

title="${META_TITLE:-HeLx UI}"
description="${META_DESCRIPTION:-HeLx UI}"

cat "$1/index_template.html" | sed \
-e "s/%META_TITLE%/$title/" \
-e "s/%META_DESCRIPTION%/$description/" \
> $1/index.html
10 changes: 9 additions & 1 deletion bin/populate_env
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ hidden_support_sections="${REACT_APP_HIDDEN_SUPPORT_SECTIONS}"
hidden_result_tabs="${REACT_APP_HIDDEN_RESULT_TABS}"
deployment_namespace="${REACT_APP_DEPLOYMENT_NAMESPACE}"
appstore_asset_branch="${REACT_APP_APPSTORE_ASSET_BRANCH}"
meta_title="${META_TITLE:-HeLx UI}"
meta_description="${META_DESCRIPTION:-HeLx UI}"


template='{
Expand All @@ -36,7 +38,11 @@ template='{
"hidden_support_sections": "%HIDDEN_SUPPORT_SECTIONS%",
"hidden_result_tabs": "%HIDDEN_RESULT_TABS%",
"deployment_namespace": "%DEPLOYMENT_NAMESPACE%",
"appstore_asset_branch": "%APPSTORE_ASSET_BRANCH%"
"appstore_asset_branch": "%APPSTORE_ASSET_BRANCH%",
"meta": {
"title": "%META_TITLE%",
"description": "%META_DESCRIPTION%"
}
}'

echo "$template" | sed \
Expand All @@ -50,4 +56,6 @@ echo "$template" | sed \
-e "s/%TRANQL_URL%/$tranql_url/" \
-e "s/%DEPLOYMENT_NAMESPACE%/$deployment_namespace/" \
-e "s/%APPSTORE_ASSET_BRANCH%/$appstore_asset_branch/" \
-e "s/%META_TITLE%/$meta_title/" \
-e "s/%META_DESCRIPTION%/$meta_description/" \
> $1
7 changes: 7 additions & 0 deletions bin/start_server
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,12 @@ if [ -z "$1" ]
echo "Usage: start_server /path/to/output/env.json"
exit 1
fi

# Create env.json file
populate_env $1
# Generate the index.html file
create_index /usr/share/nginx/static/frontend
# Move into nginx html folder
mv /usr/share/nginx/static/frontend/index.html /usr/share/nginx/html/

nginx -g "daemon off;"
Binary file modified public/favicon.ico
Binary file not shown.
12 changes: 7 additions & 5 deletions public/index.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="<%= publicUrl %>/helx-logo-blue.svg" />
<link rel="icon" type="image/x-icon" href="<%= publicUrl %>favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="HeLx UI"
content="<%= isDevelopment ? "HeLx UI" : "%META_DESCRIPTION%" %>"
/>
<link rel="apple-touch-icon" href="<%= publicUrl %>/logo192.png" />
<link rel="apple-touch-icon" href="<%= publicUrl %>logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="<%= publicUrl %>/manifest.json" />
<!--
<link rel="manifest" href="<%= publicUrl %>manifest.json" />
-->
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Expand All @@ -24,7 +26,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>HeLx UI</title>
<title><%= isDevelopment ? "HeLx UI" : "%META_TITLE%" %></title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
27 changes: 27 additions & 0 deletions src/components/bouncing-dots.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export const BouncingDots = ({ height=8, style={}, ...props }) => {
return (
// Functionality pulled from antd mobile library
<svg height={ `${ height }px` } viewBox="0 0 100 40" style={{ verticalAlign: "-0.125em", ...style }} { ...props }>
<g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
<g transform="translate(-100.000000, -71.000000)">
<g transform="translate(95.000000, 71.000000)">
<g transform="translate(5.000000, 0.000000)">
<rect fill="currentColor" x="20" y="16" width="8" height="8" rx="2">
<animate attributeName="y" from="16" to="16" dur="2s" begin="0s" repeatCount="indefinite" values="16; 6; 26; 16; 16" keyTimes="0; 0.1; 0.3; 0.4; 1">
</animate>
</rect>
<rect fill="currentColor" x="46" y="16" width="8" height="8" rx="2">
<animate attributeName="y" from="16" to="16" dur="2s" begin="0.2s" repeatCount="indefinite" values="16; 6; 26; 16; 16" keyTimes="0; 0.1; 0.3; 0.4; 1">
</animate>
</rect>
<rect fill="currentColor" x="72" y="16" width="8" height="8" rx="2">
<animate attributeName="y" from="16" to="16" dur="2s" begin="0.4s" repeatCount="indefinite" values="16; 6; 26; 16; 16" keyTimes="0; 0.1; 0.3; 0.4; 1">
</animate>
</rect>
</g>
</g>
</g>
</g>
</svg>
)
}
3 changes: 2 additions & 1 deletion src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export * from './workspaces/navigation-tab-group'
export * from './link'
export * from './notifications'
export * from './debounced-input'
export * from './bouncing-dots'
export * from './side-collapse'
export * from './info-helpers'
export * from './info-helpers'
30 changes: 25 additions & 5 deletions src/components/search/concept-card/concept-card.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Fragment, useState, useEffect, useMemo, forwardRef } from 'react'
import PropTypes from 'prop-types'
import { Badge, Card, Space, Typography } from 'antd'
import { ExpandOutlined as ViewIcon } from '@ant-design/icons'
import { ExpandOutlined as ViewIcon, LoadingOutlined } from '@ant-design/icons'
import { useHelxSearch } from '../'
import { OverviewTab } from './overview-tab'
import { StudiesTab } from './studies-tab'
// import { CdesTab } from './cdes-tab'
import { BouncingDots } from '../../'
import { useAnalytics, useEnvironment } from '../../../contexts'
import classNames from 'classnames'
import './concept-card.css'
Expand All @@ -23,11 +24,30 @@ export const ConceptCard = forwardRef(({ index, result, openModalHandler, icon=V
const { context } = useEnvironment()
const { query, fetchVariablesForConceptId, fetchCDEs } = useHelxSearch()

const studyTitle = useMemo(() => (
<div style={{ display: "inline" }}>
{ !studies && (
<LoadingOutlined style={{ fontSize: 10, marginRight: 8 }} spin />
) }
Studies
{ studies && ` (${ Object.keys(studies).length })` }
</div>
), [studies])
const cdeTitle = useMemo(() => (
<div style={{ display: "inline" }}>
{ !cdeStudies && (
<LoadingOutlined style={{ fontSize: 10, marginRight: 8 }} spin />
) }
CDEs
{ cdeStudies && ` (${ Object.keys(cdeStudies).length })` }
</div>
), [cdeStudies])

const tabs = useMemo(() => ({
'overview': { title: 'Overview', content: <OverviewTab result={ result } /> },
'studies': { title: `Studies`, content: <StudiesTab studies={ studies } /> },
'cdes': { title: `CDEs`, content: <StudiesTab studies={ cdeStudies } /> },
}), [result, studies, cdeStudies])
'overview': { title: 'Overview', content: <OverviewTab result={ result } /> },
'studies': { title: studyTitle, content: <StudiesTab studies={ studies } /> },
'cdes': { title: cdeTitle, content: <StudiesTab studies={ cdeStudies } /> },
}), [result, studies, cdeStudies, studyTitle, cdeTitle])

context.hidden_result_tabs.forEach((tab) => {
delete tabs[tab]
Expand Down
23 changes: 17 additions & 6 deletions src/components/search/concept-modal/concept-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import CustomIcon, {
} from '@ant-design/icons'
import { CdesTab, OverviewTab, StudiesTab, KnowledgeGraphsTab, TranQLTab } from './tabs'
import { useHelxSearch } from '../'
import { BouncingDots } from '../../'
import { useAnalytics, useEnvironment } from '../../../contexts'
import { kgLink } from '../../../utils'
import './concept-modal.css'
Expand Down Expand Up @@ -84,13 +85,23 @@ export const ConceptModalBody = ({ result }) => {
const fetchCdesTranqlController = useRef([])
const fetchKgsController = useRef()

const studyTitle = (
<div style={{ display: "inline" }}>
Studies { studies ? `(${ Object.keys(studies).length })` : <BouncingDots /> }
</div>
)
const cdeTitle = (
<div style={{ display: "inline" }}>
CDEs { cdes ? `(${ Object.keys(cdes).length })` : <BouncingDots /> }
</div>
)

const tabs = {
'overview': { title: 'Overview', icon: <OverviewIcon />, content: <OverviewTab result={ result } />, },
'studies': { title: 'Studies', icon: <StudiesIcon />, content: <StudiesTab studies={ studies } />, },
'cdes': { title: `CDEs`, icon: <CdesIcon />, content: <CdesTab cdes={ cdes } cdeRelatedConcepts={ cdeRelatedConcepts } loading={ cdesLoading } /> },
'kgs': { title: 'Knowledge Graphs', icon: <KnowledgeGraphsIcon />, content: <KnowledgeGraphsTab graphs={ graphs } />, },
'tranql': { title: 'TranQL', icon: <TranQLIcon />, content: <TranQLTab result={ result } graphs = { graphs } /> },
// 'robokop': { title: 'Robokop', icon: <RobokopIcon/>, content: <RobokopTab /> }
'overview': { title: 'Overview', icon: <OverviewIcon />, content: <OverviewTab result={ result } />, },
'studies': { title: studyTitle, icon: <StudiesIcon />, content: <StudiesTab studies={ studies } />, },
'cdes': { title: cdeTitle, icon: <CdesIcon />, content: <CdesTab cdes={ cdes } cdeRelatedConcepts={ cdeRelatedConcepts } loading={ cdesLoading } /> },
'kgs': { title: 'Knowledge Graphs', icon: <KnowledgeGraphsIcon />, content: <KnowledgeGraphsTab graphs={ graphs } />, },
'tranql': { title: 'TranQL', icon: <TranQLIcon />, content: <TranQLTab result={ result } graphs = { graphs } /> }
}
const links = {
'robokop' : { title: 'ROBOKOP', icon: <RobokopIcon/>, url: "https://robokop.renci.org/" }
Expand Down
2 changes: 2 additions & 0 deletions src/components/search/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ export const HelxSearch = ({ children }) => {

useEffect(() => {
setConceptPages({})
setError({})
setTypeFilter(null)
setSelectedResult(null)
setVariableStudyResults([])
Expand Down Expand Up @@ -279,6 +280,7 @@ export const HelxSearch = ({ children }) => {
} catch (error) {
console.log(error)
setError({ message: 'An error occurred!' })
setTotalConcepts(0)
setIsLoadingConcepts(false)
analyticsEvents.searchExecuted(query, Date.now() - startTime, 0, error)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Fragment, useMemo, useCallback } from 'react'
import { Spin, Grid as AntGrid, Typography, Radio, Tooltip } from 'antd'
import { Spin, Grid as AntGrid, Typography, Radio, Tooltip, Empty } from 'antd'
import { ConceptCard, useHelxSearch, SearchLayout, ExpandedResultsLayout } from '../../'
import InfiniteScroll from 'react-infinite-scroll-component'
import { BackTop } from '../../../layout'
Expand All @@ -9,8 +9,8 @@ const { Text } = Typography
const { useBreakpoint } = AntGrid

export const ConceptSearchResults = () => {
const { query, conceptPages, perPage, currentPage, pageCount, typeFilter, isLoadingVariableResults,
isLoadingConcepts, error, layout, setCurrentPage, setSelectedResult } = useHelxSearch()
const { query, conceptPages, perPage, currentPage, pageCount, typeFilter,
isLoadingConcepts, error, setCurrentPage, setSelectedResult } = useHelxSearch()
const { md } = useBreakpoint();
const concepts = useMemo(() => Object.values(conceptPages).flat(), [conceptPages])
const hasMore = useMemo(() => (
Expand All @@ -25,9 +25,17 @@ export const ConceptSearchResults = () => {
return (
<Fragment>
{
query && !error.message && (
query && (
<Fragment>
<div className="results" style={{ flexGrow: 1 }}>
{ error.message ? (
<span style={{ marginTop: -144, padding: "0 6px" }}>{ error.message }</span>
) : concepts.length === 0 && !isLoadingConcepts ? (
<Empty style={{ marginTop: -24 }} description={
<Text type="secondary">No results were found for &quot;{ query }&quot;</Text>
} />
// <span style={{ marginTop: -144, padding: "0 6px" }}>No results found</span>
) : null }
{concepts.length > 0 && <ResultsHeader />}
<InfiniteScroll
dataLength={concepts.length}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ import { ConceptSearchResults } from './concept-search-results'
import { useHelxSearch, SearchForm } from '../../'

export const ConceptsGridLayout = () => {
const { error } = useHelxSearch()
return (
<Fragment>
<SearchForm />
{ error && <span>{ error.message }</span> }
<ConceptSearchResults />
</Fragment>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { Fragment, useEffect, useState } from 'react'
import { Divider, Grid, Spin } from 'antd'
import { Divider, Grid, Spin, Typography, Empty } from 'antd'
import { SearchForm, useHelxSearch } from '../..'
import { ExpandedResultsSidebar } from './expanded-results-sidebar'
import { ExpandedResultsContent } from './expanded-results-content'
import { ResultsHeader } from '..'
import classNames from 'classnames'
import './expanded-results-layout.css'


const { Text } = Typography
const { useBreakpoint } = Grid

export const ExpandedResultsLayout = () => {
const { selectedResult, setSelectedResult, concepts, totalConcepts, isLoadingConcepts, query } = useHelxSearch()
const { selectedResult, setSelectedResult, concepts, totalConcepts, isLoadingConcepts, query, error } = useHelxSearch()
const { md } = useBreakpoint()

const [expanded, setExpanded] = useState(true)
Expand Down Expand Up @@ -52,6 +54,14 @@ export const ExpandedResultsLayout = () => {
{isLoadingConcepts && totalConcepts === 0 && (
<Spin style={{ display: 'block', margin: '4rem', flexGrow: 1 }} />
)}
{ error.message ? (
<span style={{ marginTop: -144, padding: "0 6px" }}>{ error.message }</span>
) : concepts.length === 0 && !isLoadingConcepts ? (
<Empty style={{ marginTop: -24 }} description={
<Text type="secondary">No results were found for &quot;{ query }&quot;</Text>
} />
// <span style={{ marginTop: -144, padding: "0 6px" }}>No results found</span>
) : null }
{totalConcepts > 0 && (
<Fragment>
{/* { md && <Divider style={{ marginBottom: 0 }} /> } */}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
.variable-histogram-collapse-panel > .ant-collapse-header {
padding: 0 !important;
align-items: center !important;
margin-bottom: 16px;
}
.variable-histogram-collapse-panel > .ant-collapse-content > .ant-collapse-content-box {
padding: 0 !important;
}

.histogram-startover-btn {
margin-bottom: 10px;
}
Expand Down
Loading

0 comments on commit 181b300

Please sign in to comment.