Skip to content

Commit

Permalink
Merge branch 'master' into ui-4
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-aksamentov committed Oct 20, 2023
2 parents 94761f6 + e2aff98 commit ba109df
Show file tree
Hide file tree
Showing 20 changed files with 291 additions and 470 deletions.
27 changes: 22 additions & 5 deletions packages_rs/nextclade-web/src/components/Common/PreviewWarning.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,46 @@
import React, { useMemo } from 'react'
import { Alert } from 'reactstrap'
import { atom } from 'recoil'
import { useRecoilToggle } from 'src/hooks/useToggle'
import styled from 'styled-components'
import { useTranslationSafe as useTranslation } from 'src/helpers/useTranslationSafe'
import { UncontrolledAlert } from 'reactstrap'

import { RELEASE_URL } from 'src/constants'
import { LinkExternal } from 'src/components/Link/LinkExternal'

const previewWarningDismissedAtom = atom({
key: 'previewWarningDismissedAtom',
default: false,
})

export function shouldRenderPreviewWarning(): boolean {
return process.env.NODE_ENV !== 'development' && (process.env.BRANCH_NAME ?? '') !== 'release'
}

export function PreviewWarning() {
const { t } = useTranslation()
const { state: dismissed, enable: setDismissed } = useRecoilToggle(previewWarningDismissedAtom)

const warningText = useMemo(() => t('This is a preview version. For official website please visit '), [t])

if (!shouldRenderPreviewWarning()) {
if (!shouldRenderPreviewWarning() || dismissed) {
return null
}

return (
<UncontrolledAlert color="warning" className="text-center m-0" fade={false}>
<Warning color="warning" fade={false} isOpen toggle={setDismissed}>
<span>{warningText}</span>
<span>
<LinkExternal href={RELEASE_URL}>{RELEASE_URL}</LinkExternal>
</span>
</UncontrolledAlert>
</Warning>
)
}

const Warning = styled(Alert)`
font-size: 0.9rem;
text-align: center;
margin: 0;
padding: 5px 3px;
border-radius: 0;
z-index: 1010;
`
1 change: 0 additions & 1 deletion packages_rs/nextclade-web/src/components/Layout/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ const Container = styled.footer`
bottom: 0;
padding: 6px 10px;
box-shadow: ${(props) => props.theme.shadows.large};
z-index: 1000;
background-color: ${(props) => props.theme.white};
opacity: 1;
`
Expand Down
7 changes: 5 additions & 2 deletions packages_rs/nextclade-web/src/components/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const Container = styled.div`

const HeaderWrapper = styled.header`
height: 45px;
z-index: 1001;
`

const MainInner = styled.main`
Expand All @@ -34,21 +35,23 @@ const MainOuter = styled.main`
display: flex;
flex-direction: column;
flex: 1;
flex-direction: column;
overflow: hidden;
height: 100%;
width: 100%;
padding: 0;
margin: 0;
`

const FooterWrapper = styled.footer``
const FooterWrapper = styled.footer`
z-index: 1001;
`

export function Layout({ children }: PropsWithChildren<HTMLProps<HTMLDivElement>>) {
return (
<Container>
<PreviewWarning />
<BrowserWarning />

<HeaderWrapper>
<NavigationBar />
</HeaderWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import { BsCaretRightFill as ArrowRight } from 'react-icons/bs'
import { Link } from 'src/components/Link/Link'
import { FaDocker, FaGithub, FaXTwitter, FaDiscourse } from 'react-icons/fa6'
import { LinkSmart } from 'src/components/Link/LinkSmart'
import { hasRanAtom, hasTreeAtom } from 'src/state/results.state'
import { ResultsStatus } from 'src/components/Results/ResultsStatus'
import { canDownloadAtom, hasRanAtom, hasTreeAtom } from 'src/state/results.state'
import styled, { useTheme } from 'styled-components'
import { useTranslationSafe } from 'src/helpers/useTranslationSafe'
import BrandLogoBase from 'src/assets/img/nextclade_logo.svg'
Expand Down Expand Up @@ -132,6 +133,7 @@ export function NavigationBar() {

const hasTree = useRecoilValue(hasTreeAtom)
const hasRan = useRecoilValue(hasRanAtom)
const canDownload = useRecoilValue(canDownloadAtom)

const linksLeft = useMemo(() => {
return [
Expand All @@ -147,9 +149,9 @@ export function NavigationBar() {
title: hasTree ? t('Show phylogenetic tree') : t('Please run the analysis on a dataset with reference tree'),
},
{
url: hasRan ? '/export' : undefined,
url: canDownload ? '/export' : undefined,
content: t('Export'),
title: hasRan ? t('Export results') : t('Please run the analysis first.'),
title: canDownload ? t('Export results') : t('Please run the analysis first.'),
},
].map((desc, i) => {
const link = <NavLinkBreadcrumb key={desc.url ?? desc.title} desc={desc} active={pathname === desc.url} />
Expand All @@ -159,7 +161,7 @@ export function NavigationBar() {
const arrow = <BreadcrumbArrow key={`arrow-${desc.url ?? desc.title}`} disabled={!desc.url} />
return [arrow, link]
})
}, [hasRan, hasTree, pathname, t])
}, [canDownload, hasRan, hasTree, pathname, t])

const linksRight = useMemo(() => {
return [
Expand Down Expand Up @@ -221,6 +223,9 @@ export function NavigationBar() {

{linksLeft}
</Nav>

<ResultsStatus />

<Nav className="ml-auto">{linksRight}</Nav>
</Navbar>
)
Expand Down
50 changes: 27 additions & 23 deletions packages_rs/nextclade-web/src/components/Loading/Loading.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import React from 'react'

import React, { HTMLProps } from 'react'
import { useTranslationSafe as useTranslation } from 'src/helpers/useTranslationSafe'

import BrandLogoBase from 'src/assets/img/nextclade_logo.svg'
import styled from 'styled-components'

const LOADING_LOGO_SIZE = 150
const LOADING_SPINNER_THICKNESS = 17
import { StrictOmit } from 'ts-essentials'

const Container = styled.div`
display: flex;
Expand All @@ -29,29 +25,29 @@ const Container = styled.div`
}
`

const BrandLogo = styled(BrandLogoBase)`
const BrandLogo = styled(BrandLogoBase)<{ $size: number }>`
margin: auto;
width: ${LOADING_LOGO_SIZE}px;
height: ${LOADING_LOGO_SIZE}px;
width: ${(props) => props.$size}px;
height: ${(props) => props.$size}px;
box-shadow: 0 0 0 0 rgba(0, 0, 0, 1);
`

const SpinnerAnimation = styled.div`
const SpinnerAnimation = styled.div<{ $size: number }>`
margin: auto;
display: flex;
width: ${LOADING_LOGO_SIZE + LOADING_SPINNER_THICKNESS}px;
height: ${LOADING_LOGO_SIZE + LOADING_SPINNER_THICKNESS}px;
width: ${(props) => props.$size * 1.2}px;
height: ${(props) => props.$size * 1.2}px;
overflow: hidden;
border-radius: 10px;
border-radius: ${(props) => props.$size * 0.15}px;
--c1: linear-gradient(90deg, #0000 calc(100% / 3), var(--c0) 0 calc(2 * 100% / 3), #0000 0);
--c2: linear-gradient(0deg, #0000 calc(100% / 3), var(--c0) 0 calc(2 * 100% / 3), #0000 0);
background: var(--c1), var(--c2), var(--c1), var(--c2);
background-size: 300% 20px, 20px 300%;
background-size: 300% ${(props) => props.$size * 0.2}px, ${(props) => props.$size * 0.2}px 300%;
background-repeat: no-repeat;
animation: snake 1.25s infinite linear;
animation: snake 1s infinite linear;
@keyframes snake {
0% {
background-position: 50% 0, 100% 100%, 0 100%, 0 0;
Expand Down Expand Up @@ -83,17 +79,25 @@ const SpinnerAnimation = styled.div`
}
`

function Loading() {
export interface LoadingProps extends StrictOmit<HTMLProps<HTMLDivElement>, 'children' | 'ref' | 'as'> {
size: number
}

export function LoadingSpinner({ size, ...rest }: LoadingProps) {
return (
<SpinnerAnimation $size={size} {...rest}>
<BrandLogo $size={size} />
</SpinnerAnimation>
)
}

function LoadingComponent({ size, ...rest }: LoadingProps) {
const { t } = useTranslation()
return (
<Container title={t('Loading...')}>
<SpinnerAnimation>
<BrandLogo />
</SpinnerAnimation>
<Container title={t('Loading...')} {...rest}>
<LoadingSpinner size={size} />
</Container>
)
}

export default Loading

export const LOADING = <Loading />
export const LOADING = <LoadingComponent size={150} />
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export const Li = styled.li<{ $active?: boolean; $isDimmed?: boolean }>`
${(props) =>
props.$active &&
`
color: ${props.theme.white};
background-color: ${lighten(0.033)(props.theme.primary)};
color: ${props.theme.gray100};
box-shadow: -3px 3px 12px 3px #0005;
Expand Down
31 changes: 0 additions & 31 deletions packages_rs/nextclade-web/src/components/Results/ButtonBack.tsx

This file was deleted.

26 changes: 21 additions & 5 deletions packages_rs/nextclade-web/src/components/Results/ButtonFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, { useCallback } from 'react'
import { FaFilter } from 'react-icons/fa'
import { useSetRecoilState } from 'recoil'

import { PanelButton } from 'src/components/Results/PanelButton'
import type { ButtonProps } from 'reactstrap'
import { Button } from 'reactstrap'
import styled from 'styled-components'
import { useTranslationSafe } from 'src/helpers/useTranslationSafe'
import { isResultsFilterPanelCollapsedAtom } from 'src/state/settings.state'

export function ButtonFilter() {
export function ButtonFilter({ ...rest }: ButtonProps) {
const { t } = useTranslationSafe()

const setIsResultsFilterPanelCollapsed = useSetRecoilState(isResultsFilterPanelCollapsedAtom)
Expand All @@ -17,8 +18,23 @@ export function ButtonFilter() {
)

return (
<PanelButton onClick={toggleFilterPanel} title={t('Filter: opens panel where you can apply table row filtering')}>
<FaFilter size={15} />
<PanelButton
color="secondary"
onClick={toggleFilterPanel}
title={t('Filter: opens panel where you can apply table row filtering')}
{...rest}
>
<FaFilter size={12} />
</PanelButton>
)
}

export const PanelButton = styled(Button)`
margin: auto 0;
left: 20px;
top: -4px;
height: 36px;
width: 36px;
padding: 0;
color: ${(props) => props.theme.gray600};
`
Loading

0 comments on commit ba109df

Please sign in to comment.