Commit 56802dfe authored by Viacheslav Pavlov's avatar Viacheslav Pavlov Committed by Matija Obreza

SidebarWrapper, FiltersBlock and Stepper template updated

parent b53eb0fe
......@@ -1421,6 +1421,7 @@
"public": {
"p": {
"stepper": {
"stepperTitle": "Requesting samples from holding institutes",
"accessionsList": {
"title": "Out of {{count, number}} accessions listed, {{available, number}} are known to be available for distribution.",
"stepName": "Review list of material"
......@@ -1533,6 +1534,7 @@
},
"p": {
"stepper": {
"stepperTitle": "Steps for subset data publication completion",
"accessionList": {
"stepName": "List of accessions",
"instructions": "INSTRUCTIONS FOR USE",
......
......@@ -2,6 +2,7 @@
"public": {
"p": {
"stepper": {
"stepperTitle": "Requesting samples from holding institutes",
"accessionsList": {
"title": "Out of {{count, number}} accessions listed, {{available, number}} are known to be available for distribution.",
"stepName": "Review list of material"
......
......@@ -76,6 +76,7 @@ const mapStateToProps = (state, ownProps) => ({
needLoading: false,
showHeader: false,
pageTitle: ownProps.route.extraProps.title, // route-configured
stepperTitle: 'requests.public.p.stepper.stepperTitle',
location: ownProps.location,
});
......
......@@ -49,6 +49,7 @@
},
"p": {
"stepper": {
"stepperTitle": "Steps for subset data publication completion",
"accessionList": {
"stepName": "List of accessions",
"instructions": "INSTRUCTIONS FOR USE",
......
......@@ -22,6 +22,7 @@ class StepperPage extends StepperPageTemplate<Subset> {
const mapStateToProps = (state, ownProps) => ({
steps,
path: 'subsets',
stepperTitle: 'subsets.dashboard.p.stepper.stepperTitle',
item: state.subsets.dashboard.subset,
pageTitle: ownProps.route.extraProps.title, // route-configured
location: ownProps.location,
......
......@@ -17,13 +17,13 @@ const styles = (theme) => ({
},
stickyButtonContainer: {
position: 'sticky' as 'sticky',
bottom: '2rem',
width: 'calc(100% - 35px)',
boxShadow: '0px 4px 8px -1px rgba(0, 0, 0, 0.2)',
boxSizing: 'border-box' as 'border-box',
top: '0',
zIndex: 10,
width: '100%',
backgroundColor: '#fff',
overflow: 'hidden' as 'hidden',
[theme.breakpoints.down('sm')]: {
bottom: '3rem',
},
},
btnGreen: theme.buttons.green,
btnReset: theme.buttons.reset,
......@@ -57,11 +57,11 @@ const FiltersBlock = ({ title, children, handleSubmit, onSubmit, initialize, cla
<div className={ classes.filtersBlock }>
<ExpandFiltersComponent title={ title || 'Filters' }>
<form onSubmit={ processSubmit }>
{ children }
<div className={ `pt-20 pb-20 pl-20 ${classes.stickyButtonContainer}` }>
<div className={ `pt-20 pb-20 pl-20 ${classes.stickyButtonContainer}` }>
<Button variant="contained" onClick={ processSubmit } type="submit" className={ `${classes.btnGreen} float-left` }>{ t('common:action.applyFilters') }</Button>
<Button onClick={ onReset } type="button" className={ `${classes.btnReset} float-right` }>{ t('common:action.reset') }</Button>
</div>
{ children }
</form>
</ExpandFiltersComponent>
</div>
......
......@@ -45,12 +45,14 @@ const styles = (theme) => ({
},
},
/* tslint:enable */
flexGrow: {
flex: '1 1 auto',
},
header: {
display: 'flex' as 'flex',
justifyContent: 'space-between' as 'space-between',
alignItems: 'center' as 'center',
padding: '20px',
[theme.breakpoints.down('sm')]: {
flexWrap: 'wrap' as 'wrap',
},
},
title: {
lineHeight: '1.524em',
......@@ -133,25 +135,26 @@ class StepNavigation extends React.Component<IStepNavigationProps, any> {
showStepName && `${this.state.id}. ${t(steps.find((e) => e.id === this.state.id).name)}`
}
</h3>
<div className={ classes.flexGrow }/>
{ this.state.id === 1 && (
<Button disabled={ disabled } onClick={ onDelete } className={ classes.btnDelete }>
{ t('common:action.deleteData') }
</Button>
)
}
{ this.state.id > 1 && (
<Button onClick={ () => onGotoStep(this.state.id - 1) } className={ classes.btnReturn }>
{ t('common:action.return') }
</Button>
)
}
{ this.state.id !== steps.length && (
<Button disabled={ disabledNext } variant="contained" onClick={ () => onGotoStep(this.state.id + 1) } className={ classes.btnBlue }>
{ t('common:action.nextStep') }
</Button>
) }
{ this.state.id === steps.length && actionButtons }
<div>
{ this.state.id === 1 && (
<Button disabled={ disabled } onClick={ onDelete } className={ classes.btnDelete }>
{ t('common:action.deleteData') }
</Button>
)
}
{ this.state.id > 1 && (
<Button onClick={ () => onGotoStep(this.state.id - 1) } className={ classes.btnReturn }>
{ t('common:action.return') }
</Button>
)
}
{ this.state.id !== steps.length && (
<Button disabled={ disabledNext } variant="contained" onClick={ () => onGotoStep(this.state.id + 1) } className={ classes.btnBlue }>
{ t('common:action.nextStep') }
</Button>
) }
{ this.state.id === steps.length && actionButtons }
</div>
</Grid>
{ bottomDivider && <Divider/> }
</Grid>
......
......@@ -22,6 +22,7 @@ interface IStepperTemplateProps extends React.ClassAttributes<any> {
onApprove: any;
steps: any;
stillLoading: any;
stepperTitle: any;
pageTitle: any;
path: string;
location: any;
......@@ -74,14 +75,19 @@ class StepperTemplate<T> extends React.Component<T & IStepperTemplateProps> {
public render() {
const {disabled, steps, stillLoading, pageTitle, path, location, showHeader, t} = this.props;
const {disabled, steps, stillLoading, pageTitle, path, location, showHeader, t, stepperTitle} = this.props;
const {disabledProgress} = this.state;
const child = this.renderContent();
const stepNavigation = this.getStepNavigation();
return (
<ContentLayout right={
<ProgressMenu disabled={ disabledProgress || disabled } onGotoStep={ this.gotoStep } steps={ steps }
location={ location }/>
<ProgressMenu
stepperTitle={ stepperTitle }
disabled={ disabledProgress || disabled }
onGotoStep={ this.gotoStep }
steps={ steps }
location={ location }
/>
} customHeaderHeight>
{ showHeader && <TopSection pageTitle={ t(pageTitle) } backTarget={ `/dashboard/${path}` }/> }
<Grid container spacing={ 0 }>
......
......@@ -9,6 +9,7 @@ import StepsListItem from './StepsListItem';
interface IProgressMenuProps extends React.ClassAttributes<any> {
disabled: boolean;
stepperTitle: string;
classes: any;
location: any;
steps: any;
......@@ -19,7 +20,7 @@ interface IProgressMenuProps extends React.ClassAttributes<any> {
const styleSheet = (theme) => ({
/* tslint:disable */
root: {
position: 'sticky' as 'sticky',
position: 'static' as 'static',
// top: '6rem',
width: '100%',
// height: '100%',
......@@ -31,20 +32,25 @@ const styleSheet = (theme) => ({
},
boxShadow: '-4px 0px 2px -1px rgba(0, 0, 0, 0.2)',
},
steps: {
position: 'absolute' as 'absolute',
width: '100%',
}
});
class ProgressMenu extends React.Component<IProgressMenuProps, any> {
public render() {
const {classes, disabled, steps, onGotoStep, location: {pathname}, t} = this.props;
const {classes, disabled, steps, onGotoStep, location: {pathname}, t, stepperTitle} = this.props;
const link = pathname.split('/').pop();
return (
<List className={ classes.root }>
<ListItem divider>
<ListItemText primary={ t('common:label.stepsForDataPublication') }/>
<ListItemText primary={ t(stepperTitle) || t('common:label.stepsForDataPublication') }/>
</ListItem>
<div className={ classes.steps }>
{
steps.map((step, i) => (
<StepsListItem
......@@ -58,6 +64,7 @@ class ProgressMenu extends React.Component<IProgressMenuProps, any> {
),
)
}
</div>
</List>
);
}
......
......@@ -36,7 +36,7 @@ const ContentLayout = ({classes, children = null, left = null, right = null, cus
{ children }
</main>
) }
{ right && (<SidebarWrapper sidebarContent={ right } customHeight={ customHeaderHeight }/>) }
{ right && (<SidebarWrapper sidebarContent={ right } customHeight={ customHeaderHeight } right/>) }
</div>
</div>
);
......
......@@ -17,6 +17,7 @@ interface ISidebarProps extends React.ClassAttributes<any> {
isOpen: boolean;
width: Breakpoint;
customHeight?: boolean;
right?: boolean;
}
const mobile = ['sm', 'xs'] as Breakpoint[];
......@@ -25,7 +26,7 @@ const styles = (theme) => ({
/* tslint:disable */
drawer: {
'-webkit-transform': 'translateZ(0);',
boxShadow: '-4px 0px 2px -1px rgba(0, 0, 0, 0.2)',
position: 'sticky' as 'sticky',
top: '72px',
zIndex: 10,
......@@ -34,17 +35,21 @@ const styles = (theme) => ({
'& > div': {
top: 'auto' as 'auto',
position: 'initial' as 'initial',
height: '100%' as '100%'
height: '100%' as '100%',
overflow: 'visible',
},
[theme.breakpoints.down('md')]: {
height: 'calc(100vh - 3rem)',
top: '3rem',
},
[theme.breakpoints.down('sm')]: {
maxWidth: '90%',
position: 'fixed' as 'fixed',
zIndex: 15,
}
[theme.breakpoints.down('md')]: {
height: 'calc(100vh - 3.5rem)',
top: '3.5rem',
},
[theme.breakpoints.down('sm')]: {
maxWidth: '90%',
position: 'fixed' as 'fixed',
zIndex: 15,
},
[theme.breakpoints.down('xs')]: {
maxWidth: '100%',
}
},
drawerHeightV2: {
top: '83px',
......@@ -54,33 +59,36 @@ const styles = (theme) => ({
top: '3.5rem',
},
},
drawerRight: {
right: '0',
},
drawerCollapsed: {
[theme.breakpoints.down('sm')]: {
width: 'auto',
position: 'fixed' as 'fixed',
height: 'auto',
top: '50%',
}
[theme.breakpoints.down('sm')]: {
minWidth: 'auto',
width: 'auto',
position: 'sticky' as 'sticky',
}
},
sidebar: {
whiteSpace: 'nowrap' as 'nowrap',
minWidth: '240px',
minWidth: '320px',
width: 'auto',
height: '100%',
display: 'flex' as 'flex',
flexDirection: 'column' as 'column',
justifyContent: 'flex-start' as 'flex-start',
transition: theme.transitions.create('min-width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
sidebarCollapsed: {
height: '10rem',
overflowX: 'hidden' as 'hidden',
transition: theme.transitions.create('min-width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
cursor: 'e-resize',
minWidth: theme.spacing.unit * 3,
// maxWidth: theme.spacing.unit * 7,
[theme.breakpoints.up('sm')]: {
maxWidth: theme.spacing.unit * 9,
},
......@@ -98,25 +106,27 @@ const styles = (theme) => ({
},
sidebarContents: {
width: '100%',
minHeight: 'calc(100% - 2rem)',
height: 'auto' as 'auto',
overflow: 'auto' as 'auto',
[theme.breakpoints.down('sm')]: {
minHeight: 'calc(100% - 3rem)',
},
},
sidebarContentsCollapsed: {
minHeight: 'calc(100% - 52px)',
whiteSpace: 'nowrap' as 'nowrap',
[theme.breakpoints.down('sm')]: {
minHeight: 'calc(100% - 38px)',
},
},
/* tslint:disable */
collapseButton: {
display: 'none',
width: '100%',
position: 'sticky' as 'sticky',
backgroundColor: '#e6e6e6',
height: '2rem',
bottom: 0,
height: '3rem',
flex: '1 1 100%',
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
......@@ -139,15 +149,36 @@ const styles = (theme) => ({
},
},
[theme.breakpoints.down('sm')]: {
height: '3rem',
marginTop: '3rem',
maxWidth: '100%%',
position: 'fixed' as 'fixed'
display: 'block' as 'block',
},
},
buttonCollapsed: {
display: 'none' as 'none'
}
top: '100%',
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
display: 'flex' as 'flex',
alignItems: 'center' as 'center',
'& > svg':{
'html[dir="rtl"] &' : {
transform: 'rotate(180deg)',
},
}
},
pageContent: {
zIndex: -2,
backgroundColor: '#878787',
opacity: 0.4,
position: 'fixed' as 'fixed',
width: '100%',
height: '100%',
top: 0,
left: 0,
[theme.breakpoints.up('md')]: {
display: 'none' as 'none',
},
},
});
class SidebarWrapper extends React.Component<ISidebarProps, any> {
......@@ -161,38 +192,45 @@ class SidebarWrapper extends React.Component<ISidebarProps, any> {
}
public render() {
const { sidebarContent, classes, isOpen, width, customHeight } = this.props;
const { sidebarContent, classes, isOpen, width, customHeight, right = false } = this.props;
const isMobile = mobile.indexOf(width) !== -1;
return (
<SidebarDrawer
className={ `${classes.drawer} ${!isOpen ? classes.drawerCollapsed : ''} ${customHeight ? classes.drawerHeightV2 : ''}` }
className={ `
${classes.drawer}
${!isOpen ? classes.drawerCollapsed : ''}
${customHeight ? classes.drawerHeightV2 : ''}
${right ? classes.drawerRight : ''}
` }
isOpen={ isOpen }
variant={ 'permanent' }
>
{ isOpen &&
{ (!isMobile || isOpen) &&
<div className={ `${ classes.sidebar }` }>
<div
onClick={() => { this.setIsCollapsed(true); }}
className={ `${classes.collapseButton}` }>
<span>
{ right ? (<ChevronRight />):(<ChevronLeft />) } Collapse
</span>
</div>
<div className={ classes.sidebarContents }>
{ sidebarContent }
</div>
<div
onClick={() => { this.setIsCollapsed(true); }}
className={ `${classes.collapseButton}` }>
<span><ChevronLeft /> Collapse</span>
</div>
<div className={classes.pageContent} onClick={() => { isMobile ? this.setIsCollapsed(true) : null; } }> </div>
</div>
}
{ !isOpen &&
{ (!isOpen && isMobile) &&
<div className={ `${ classes.sidebar } ${classes.sidebarCollapsed}` }>
<div className={ `${classes.sidebarContents} ${classes.sidebarContentsCollapsed}` } onClick={() => { this.setIsCollapsed(false); }}>
<p className={ classes.collapsedText }>Open sidebar</p>
</div>
<div
onClick={() => { this.setIsCollapsed(false); }}
className={ `${classes.collapseButton} ${classes.buttonCollapsed}` }
onClick={() => { this.setIsCollapsed(false); }}
className={ `${classes.collapseButton} ${classes.buttonCollapsed}` }
>
<ChevronRight />
{ right ? (<ChevronLeft />):(<ChevronRight />) }
</div>
<div className={ `${classes.sidebarContents} ${classes.sidebarContentsCollapsed}` } onClick={() => { this.setIsCollapsed(false); }}>
<p className={ classes.collapsedText }>Open sidebar</p>
</div>
</div>
}
......
......@@ -18,6 +18,7 @@ interface IStepperProps<T> extends React.ClassAttributes<any> {
path: string;
uuid: string;
pageTitle: string;
stepperTitle: string;
item: any;
needLoading: boolean;
showHeader: boolean;
......@@ -113,12 +114,14 @@ class StepperTemplate<T, P> extends React.Component<IStepperProps<T> & P, any> {
const {item} = this.props;
const stillLoading: boolean = needLoading && (!item || (uuid && (item.uuid !== uuid)));
const disabled: boolean = needLoading && !(item && item.uuid);
const stepperTitle = this.props.stepperTitle || pageTitle;
return (
<div>
{
renderRoutes(route.routes, match.path,
{
stepperTitle,
stillLoading,
steps,
item,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment