Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
363e2b3
scaffold out cart context provider
mbwatson Feb 11, 2022
f275bb3
wrap application in context provider
mbwatson Feb 11, 2022
b2bcd0f
add shopping cart link to main menu
mbwatson Feb 11, 2022
bd5cbf3
create shopping cart view
mbwatson Feb 11, 2022
4576ff1
tie together views, menus, and routes
mbwatson Feb 11, 2022
4529ab7
merge
frostyfan109 Jul 19, 2022
1446b85
Upgrade react-scripts and fix associated errors
frostyfan109 Jul 19, 2022
db334fc
Rework shopping cart into popover + full view. Begin templating its i…
frostyfan109 Jul 19, 2022
163b11d
Adds basic functionality to shopping cart popup + context tweaks
frostyfan109 Jul 19, 2022
a26a87a
Add duplicate cart error. Add confirm delete for carts (with an antd …
frostyfan109 Jul 19, 2022
8c92174
Rework shopping cart UI into single interface with popups. Partially …
frostyfan109 Jul 20, 2022
a58a291
Refactor shopping cart popup into file-scoped components
frostyfan109 Jul 20, 2022
62fd5ec
Adds favoriting carts
frostyfan109 Jul 20, 2022
ebc8b82
More blueprinting of shopping cart context .Adds overflow handling on…
frostyfan109 Jul 20, 2022
08a09a3
Fix add to cart
frostyfan109 Jul 20, 2022
15b2e8e
Fix context methods
frostyfan109 Jul 20, 2022
b76cc17
List display of cart in popover
frostyfan109 Jul 20, 2022
1dcaa88
Display improvements
frostyfan109 Jul 20, 2022
0093563
Style improvements to cart popover
frostyfan109 Jul 20, 2022
fce4530
Adds cart animations. Fixes animation on buttons
frostyfan109 Jul 21, 2022
948771b
Style improvements to cart list
frostyfan109 Jul 21, 2022
e2fe02d
Improved cart animations
frostyfan109 Jul 21, 2022
53f2d33
Major refactoring to make shopping cart more customizable and encapsu…
frostyfan109 Jul 21, 2022
18fff90
Finishes basic dropdown add to cart. Lots of refactoring/changes for …
frostyfan109 Jul 22, 2022
0c7ed54
Study rendering in cart list. 'from' field appended to cart items for…
frostyfan109 Jul 22, 2022
e50ee90
Fix typo with remove study from cart list bug
frostyfan109 Jul 22, 2022
311c164
Empty cart
frostyfan109 Jul 22, 2022
ba9a3b8
Variable add to carts, refactoring, bug fixes
frostyfan109 Jul 22, 2022
0f59b80
Style improvements.
frostyfan109 Jul 22, 2022
48343fe
Refactor CartList to use CartItem and add variable items to cart list.
frostyfan109 Jul 22, 2022
1fb9b82
Fix typo
frostyfan109 Jul 22, 2022
c973f22
Moves shopping cart into its own package and adds as dependency. And …
frostyfan109 Jul 25, 2022
018c817
Fix price/tax properties.
frostyfan109 Jul 25, 2022
50736fd
Remove price field on concept cart items.
frostyfan109 Jul 25, 2022
24ad4a9
Adds checkout button functionality. Compatibility updates with shoppi…
frostyfan109 Jul 26, 2022
219a2aa
Merge develop.
frostyfan109 Jul 26, 2022
f73d248
Fix styling issues caused by merge
frostyfan109 Jul 26, 2022
91bf2b9
Blueprinting cart export view
frostyfan109 Jul 26, 2022
353cc71
Work-in-progress cart checkout/export page.
frostyfan109 Jul 28, 2022
c388939
Adds prototyped export tray to cart view. Fix bug were studies nameSe…
frostyfan109 Jul 29, 2022
b5c5997
Refactor shopping cart view into view + component
frostyfan109 Jul 29, 2022
98ca667
Fix typo caused by merge in concept studies card
frostyfan109 Jul 29, 2022
5e10eb9
Adds add to cart icon in study card tab
frostyfan109 Jul 29, 2022
461d43d
Improves extra panel in cart checkout.
frostyfan109 Jul 29, 2022
38a1ec4
Moves extra tray to antd-shopping-cart and configures it.
frostyfan109 Jul 29, 2022
826c3a3
Small styling change in accordance with shopping cart update
frostyfan109 Aug 1, 2022
d7de5f6
Adds export functionality
frostyfan109 Aug 2, 2022
abcabc7
Remove items after export feature
frostyfan109 Aug 2, 2022
3cf92b9
Refactor cart list full page layout into antd-shopping-cart package
frostyfan109 Aug 2, 2022
1b5a114
Update package
frostyfan109 Aug 2, 2022
d812c2d
Fix cart buttons in card study tab
frostyfan109 Aug 11, 2022
a6af90f
Fix bug with active-route attribute
frostyfan109 Jun 27, 2023
f3398ff
add cde section to shopping cart
Woozl Jul 6, 2023
6573ec8
sync active cart to localStorage
Woozl Jul 6, 2023
6393ea8
make header sticky
Woozl Aug 17, 2023
c1611bd
add csv export option
Woozl Aug 24, 2023
4bd6672
provide helxSearchUrl to shopping cart context for cart upload
Woozl Sep 5, 2023
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
16 changes: 12 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,29 @@
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"antd": "^4.21.7",
"antd-shopping-cart": "^1.0.7",
"axios": "^0.27.2",
"antd": "^4.20.6",
"classnames": "^2.3.1",
"elasticlunr": "^0.9.5",
"eslint": "^7.27.0",
"helx-analytics": "^1.0.14",
"js-file-download": "^0.4.12",
"lunr": "^2.3.9",
"rc-queue-anim": "^2.0.0",
"rc-texty": "^0.2.0",
"rc-tween-one": "^3.0.6",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-highlight-words": "^0.18.0",
"react-infinite-scroll-component": "^6.1.0",
"react-scripts": "4.0.3",
"react-scripts": "^5.0.1",
"react-sizeme": "^3.0.2",
"styled-components": "^5.3.0",
"timeago-react": "^3.0.2",
"use-debounce": "^7.0.0",
"web-vitals": "^1.0.1"
"web-vitals": "^1.0.1",
"yaml": "^2.1.1"
},
"scripts": {
"start": "react-scripts start",
Expand All @@ -49,5 +56,6 @@
"last 1 firefox version",
"last 1 safari version"
]
}
},
"devDependencies": {}
}
23 changes: 15 additions & 8 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
import { useEffect } from 'react'
import { LocationProvider, Router as ReachRouter, globalHistory, useLocation } from '@reach/router'
import { EnvironmentProvider, ActivityProvider, AppProvider, InstanceProvider, AnalyticsProvider, useEnvironment, useAnalytics } from './contexts'
import {
EnvironmentProvider, ActivityProvider, AppProvider,
InstanceProvider, AnalyticsProvider, ShoppingCartProvider,
useEnvironment, useAnalytics
} from './contexts'
import { Layout } from './components/layout'
import { NotFoundView } from './views'
import 'antd-shopping-cart/dist/bundle.css'

const ContextProviders = ({ children }) => {
return (
<EnvironmentProvider>
<LocationProvider>
<AnalyticsProvider>
<ActivityProvider>
<InstanceProvider>
<AppProvider>
{children}
</AppProvider>
</InstanceProvider>
</ActivityProvider>
<ShoppingCartProvider>
<ActivityProvider>
<InstanceProvider>
<AppProvider>
{children}
</AppProvider>
</InstanceProvider>
</ActivityProvider>
</ShoppingCartProvider>
</AnalyticsProvider>
</LocationProvider>
</EnvironmentProvider >
Expand Down
29 changes: 27 additions & 2 deletions src/components/layout/layout.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
.helx-header {
padding-right: 2px !important;
isolation: isolate;
position: sticky;
top: 0;
box-shadow: 0px 2px 6px 4px rgba(0,0,0,0.1);
}

.layout {
isolation: isolate;
}

.brand_img {
Expand All @@ -24,6 +32,23 @@
position: absolute;
}

.logout-button {
margin: 0 1rem 0 0.5rem;
.shopping-cart-button {
margin-left: 8px !important;
/* The header has 2px of right padding, so this corresponds to 16px (aligned halfway between main content and page end) */
margin-right: 14px !important;
}

.shopping-cart-button, .logout-button {
/* margin-left: 16px; */
}

.icon-btn {
cursor: pointer;
transition: color 0.3s ease;
}
.icon-btn:not(.no-hover):hover {
color: #40a9ff !important;
}
.icon-btn:active {
color: #096dd9 !important;
}
49 changes: 43 additions & 6 deletions src/components/layout/layout.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
import { Layout as AntLayout, Button, Menu, Grid } from 'antd'
import { useLocation, Link } from '@reach/router'
import { useEffect, useState } from 'react';
import { Layout as AntLayout, Button, Menu, Grid, Divider, Badge, Popover, Typography, Tag, Space } from 'antd'
import { ShoppingCartOutlined as ShoppingCartIcon } from '@ant-design/icons'
import { useLocation, Link, redirectTo, navigate } from '@reach/router'
import { useEnvironment, useAnalytics } from '../../contexts';
import { logoutHandler } from '../../api/';
import { MobileMenu } from './menu';
import { SidePanel } from '../side-panel/side-panel';
import { CartPopoverButton, useShoppingCart } from 'antd-shopping-cart';
import './layout.css';

const { Text, Title } = Typography
const { Header, Content, Footer } = AntLayout
const { useBreakpoint } = Grid

const ACTIVE_CART_LS_KEY = 'active_cart';

export const Layout = ({ children }) => {
const { helxAppstoreUrl, routes, context, basePath } = useEnvironment()
const { analyticsEvents } = useAnalytics()
const { md } = useBreakpoint()
const baseLinkPath = context.workspaces_enabled === 'true' ? '/helx' : ''
const location = useLocation();
const { activeCart, setActiveCart } = useShoppingCart();

// on mount, check if there is a active cart in local storage
useEffect(() => {
const stored = window.localStorage.getItem(ACTIVE_CART_LS_KEY);
if (stored) setActiveCart(stored);
}, []);

// anytime the activeCart is changed, update localStorage
useEffect(() => {
window.localStorage.setItem(ACTIVE_CART_LS_KEY, activeCart.name);
}, [activeCart]);

const logoutButton = context.workspaces_enabled === 'true'

const logout = () => {
analyticsEvents.logout()
Expand All @@ -23,7 +43,7 @@ export const Layout = ({ children }) => {

return (
<AntLayout className="layout">
<Header className="helx-header" style={{ display: 'flex', zIndex: 1, width: '100%', background: '#fff' }}>
<Header className="helx-header" style={{ display: 'flex', zIndex: 100, width: '100%', background: '#fff' }}>
{context !== undefined ? <Link to={basePath}><img className="brand_img" src={'' + context.logo_url} alt={context.brand}></img></Link> : <span />}
{md ? (
<div style={{ flexGrow: 1, display: "flex", justifyContent: "flex-end" }}>
Expand All @@ -41,17 +61,34 @@ export const Layout = ({ children }) => {
<Menu.Item key={`${baseLinkPath}${m.path}`}><Link to={`${baseLinkPath}${m.path}`}>{m.text}</Link></Menu.Item>
))}
</Menu>
{context.workspaces_enabled === 'true' && (
{/* <Divider
type="vertical"
style={{
height: "calc(100% - 16px)",
marginLeft: "8px",
marginRight: "16px",
top: 0,
marginTop: "0",
marginBottom: "0",
}}
/> */}
<div style={{ height: "100%" }}>
<CartPopoverButton
badgeProps={{ overflowCount: 99 }}
onCheckout={ () => navigate(`${baseLinkPath}/cart`) }
/>
</div>
{logoutButton && (
<div style={{ height: "100%" }}>
<Button type="primary" ghost className="logout-button" onClick={logout}>LOG OUT</Button>
<Button style={{ marginRight: 14 }} type="primary" ghost className="logout-button" onClick={logout}>LOG OUT</Button>
</div>
)}
</div>
) : (
<MobileMenu menu={routes} />
)}
</Header>
<Content className>
<Content data-active-route={ routes.find((route) => location.pathname === `${ baseLinkPath }${ route.path }`)?.path }>
{children}
{context.workspaces_enabled === 'true' && <SidePanel />}
</Content>
Expand Down
21 changes: 15 additions & 6 deletions src/components/search/concept-card/concept-card.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Fragment, useState, useEffect, forwardRef } from 'react'
import PropTypes from 'prop-types'
import { useState, forwardRef } from 'react'
import { Badge, Card, Space, Typography } from 'antd'
import { ExpandOutlined as ViewIcon } from '@ant-design/icons'
import { useHelxSearch } from '../'
import { AddToCartIconButton, useShoppingCart } from 'antd-shopping-cart'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { OverviewTab } from './overview-tab'
import { StudiesTab } from './studies-tab'
// import { CdesTab } from './cdes-tab'
import { useHelxSearch } from '../'
import { useAnalytics } from '../../../contexts'
import classNames from 'classnames'
import { useShoppingCartUtilities } from '../../../hooks'
import './concept-card.css'

const { Text } = Typography
Expand All @@ -19,6 +20,8 @@ export const ConceptCard = forwardRef(({ index, result, openModalHandler, icon=V
const { query } = useHelxSearch()
const [currentTab, setCurrentTab] = useState('overview')

const { createConceptCartItem } = useShoppingCartUtilities()

const tabs = {
'overview': { title: 'Overview', content: <OverviewTab result={ result } /> },
'studies': { title: `Studies`, content: <StudiesTab result={ result } /> },
Expand Down Expand Up @@ -51,8 +54,14 @@ export const ConceptCard = forwardRef(({ index, result, openModalHandler, icon=V
tabProps={{size: 'small'}}
activeTabKey={currentTab}
onTabChange={key => setCurrentTab(key)}
extra={ icon && <IconComponent onClick={ openModal } /> }
extra={
<div style={{ display: "flex", alignItems: "center" }}>
<AddToCartIconButton item={ createConceptCartItem(result, query) } style={{ marginLeft: 8 }} />
{ icon && <IconComponent className="icon-btn" onClick={ openModal } style={{ marginLeft: 20 }} /> }
</div>
}
actions={ [<br />] }
// style={{ border: isConceptInCart(activeCart, result) ? "1px solid #91d5ff" : undefined }}
>
{ tabContents[currentTab] }
</Card>
Expand Down
4 changes: 4 additions & 0 deletions src/components/search/concept-card/studies-tab.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { Fragment, useCallback, useEffect, useMemo, useState } from 'react'
import { List, Spin, Space, Tag, Typography, Divider } from 'antd'
import { AddToCartIconButton } from 'antd-shopping-cart'
import { useHelxSearch } from '../'
import { Link } from '../../link'
import { useShoppingCartUtilities } from '../../../hooks'

const { Text } = Typography
const { CheckableTag: CheckableFacet } = Tag

export const StudiesTab = ({ result }) => {
const { query, fetchStudyVariables, fetchCDEs } = useHelxSearch()
const { createStudyCartItem } = useShoppingCartUtilities()
const [studies, setStudies] = useState([])
const [loading, setLoading] = useState(true)
const [facets, setFacets] = useState([])
Expand Down Expand Up @@ -94,6 +97,7 @@ export const StudiesTab = ({ result }) => {
<Text className="variables-count">
{ study.elements && `${ study.elements.length } variable${ study.elements.length === 1 ? '' : 's'}` }
</Text>
{ study.elements && <AddToCartIconButton item={ createStudyCartItem(study, result) } style={{ marginLeft: 24 }} /> }
</List.Item>
) }
/>
Expand Down
3 changes: 3 additions & 0 deletions src/components/search/concept-modal/concept-modal.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@
}

.study-variables-list-item {
display: flex;
flex-direction: column;
margin-left: 4px;
padding-left: 1rem !important;
border-left: 2px solid #eee;
margin-bottom: 0.5rem;
gap: 2px !important;
}

.variable-name {
Expand Down
25 changes: 17 additions & 8 deletions src/components/search/concept-modal/concept-modal.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useRef, useState } from 'react'
import { Button, Menu, Modal, Result, Space, Spin, Typography } from 'antd'
import CustomIcon, {
import { Menu, Modal, Space, Button, Result, Spin, Typography } from 'antd'
import {
InfoCircleOutlined as OverviewIcon,
BookOutlined as StudiesIcon,
ShareAltOutlined as KnowledgeGraphsIcon,
Expand All @@ -14,7 +14,9 @@ import CustomIcon, {
import { CdesTab, OverviewTab, StudiesTab, KnowledgeGraphsTab, TranQLTab } from './tabs'
import { useHelxSearch } from '../'
import { useAnalytics, useEnvironment } from '../../../contexts'
import { useShoppingCartUtilities } from '../../../hooks'
import './concept-modal.css'
import { AddToCartDropdownButton } from 'antd-shopping-cart'

const { Text, Paragraph } = Typography

Expand Down Expand Up @@ -56,7 +58,7 @@ export const ConceptModalBody = ({ result }) => {
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 } /> },
'cdes': { title: `CDEs`, icon: <CdesIcon />, content: <CdesTab cdes={ cdes } cdeRelatedConcepts={ cdeRelatedConcepts } loading={ cdesLoading } result={ result } /> },
'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 /> }
Expand Down Expand Up @@ -274,9 +276,11 @@ export const ConceptModalBody = ({ result }) => {
}

export const ConceptModal = ({ result, visible, closeHandler }) => {
const { setFullscreenResult, setSelectedResult } = useHelxSearch()
const { setFullscreenResult, query, setSelectedResult } = useHelxSearch()
const [doFullscreen, setDoFullscreen] = useState(null)

const { createConceptCartItem } = useShoppingCartUtilities()

/**
* Essentially peforming the same thing as what a this.setState call using a callback would do.
* Need to render the modal as closed for one render in order for the modal to actually close
Expand Down Expand Up @@ -310,10 +314,15 @@ export const ConceptModal = ({ result, visible, closeHandler }) => {
bodyStyle={{ padding: `0`, minHeight: `50vh`, position: `relative` }}
cancelButtonProps={{ hidden: true }}
footer={(
<Space style={{ justifyContent: "flex-end" }}>
<Button type="ghost" onClick={ openFullscreen }>Fullscreen</Button>
<Button type="primary" onClick={ closeHandler }>Close</Button>
</Space>
<div style={{ display: "flex", alignItems: "center" }}>
<AddToCartDropdownButton
item={ createConceptCartItem(result, query) }
/>
<Space style={{ justifyContent: "flex-end" }}>
<Button type="ghost" onClick={ openFullscreen }>Fullscreen</Button>
<Button type="primary" onClick={ closeHandler }>Close</Button>
</Space>
</div>
)}
>
<ConceptModalBody result={ result } />
Expand Down
9 changes: 8 additions & 1 deletion src/components/search/concept-modal/tabs/cdes/cde-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { List, Collapse, Typography, Space, Button } from 'antd'
import { ExportOutlined } from '@ant-design/icons'
import _Highlighter from 'react-highlight-words'
import { RelatedConceptsList } from './related-concepts'
import { AddToCartIconButton } from 'antd-shopping-cart';
import { useShoppingCartUtilities } from '../../../../../hooks';

const { Text, Link } = Typography
const { Panel } = Collapse
Expand All @@ -17,8 +19,9 @@ const Section = ({ title, children }) => (
</Space>
)

export const CdeItem = ({ cde, cdeRelatedConcepts, highlight }) => {
export const CdeItem = ({ cde, cdeRelatedConcepts, highlight, result }) => {
const [collapsed, setCollapsed] = useState(false)
const { createCdeCartItem } = useShoppingCartUtilities()

const relatedConceptsSource = useMemo(() => (
cdeRelatedConcepts[cde.id]
Expand All @@ -42,6 +45,10 @@ export const CdeItem = ({ cde, cdeRelatedConcepts, highlight }) => {
<Highlighter textToHighlight={ cde.name } />
</Text>
{/* Only show the "Open study" button if the CDE has a link attached to it. */}
<AddToCartIconButton
style={{ marginLeft: 8 }}
item={ createCdeCartItem(cde, result) }
/>
{cde.e_link && (
<Button
type="text"
Expand Down
Loading