Commit 8769b698 authored by Oleksii Savran's avatar Oleksii Savran Committed by Viacheslav Pavlov

RTL layouts

RTL and layout fixes
parent a44b25d8
......@@ -14,7 +14,12 @@ const styles = (theme) => ({
overflow: 'hidden' as 'hidden',
},
layersTitle: {
'html[dir="ltr"] &' : {
paddingLeft: '8px',
},
'html[dir="rtl"] &' : {
paddingRight: '8px',
},
fontSize: '15px',
fontWeight: 700,
lineHeight: '40px',
......
......@@ -44,6 +44,9 @@ const style = (theme) => ({
'html[dir="rtl"] &' : {
margin: '1.143rem 1.429rem 0 0',
},
},
ltr: {
direction: 'ltr' as 'ltr',
}
/*tslint:enable*/
});
......@@ -92,7 +95,7 @@ const ActivityPostCard = ({classes, className, post, compact, edit, t, ...gridSi
</div>
{ !compact &&
<CardContent className="pb-10">
<div dangerouslySetInnerHTML={ {__html: post.body} } />
<div dangerouslySetInnerHTML={ {__html: post.body} } className={ classes.ltr }/>
</CardContent>
}
</Card>
......
......@@ -35,8 +35,13 @@ const styles = (theme) => ({
'& ul': {
marginTop: '30px',
padding: 0,
'html[dir="ltr"] &' : {
paddingLeft: '11px',
},
'html[dir="rtl"] &' : {
paddingRight: '11px',
},
},
'& ul > li': {
lineHeight: '30px',
},
......
......@@ -13,6 +13,7 @@ const styles = (theme) => ({
width: '100%',
minHeight: 'calc(100vh - 365px)',
margin: 0,
direction: 'ltr' as 'ltr',
},
text: {
fontFamily: 'Roboto-Light',
......@@ -33,12 +34,12 @@ const styles = (theme) => ({
'& > ul': {
marginTop: '30px',
padding: 0,
'html[dir="ltr"] &': {
// 'html[dir="ltr"] &': {
paddingLeft: '11px',
},
'html[dir="rtl"] &': {
paddingRight: '11px',
},
// },
// 'html[dir="rtl"] &': {
// paddingRight: '11px',
// },
},
'& > ul > li': {
fontSize: '18px',
......@@ -52,9 +53,9 @@ const styles = (theme) => ({
tableLayout: 'fixed' as 'fixed',
'& th': {
textAlign: 'left' as 'left',
'html[dir="rtl"] &': {
textAlign: 'right' as 'right',
},
// 'html[dir="rtl"] &': {
// textAlign: 'right' as 'right',
// },
},
'& code': {
[theme.breakpoints.down('sm')]: {
......@@ -80,9 +81,9 @@ const styles = (theme) => ({
paddingBottom: '8px',
color: '#777777',
textAlign: 'left' as 'left',
'html[dir="rtl"] &': {
textAlign: 'right' as 'right',
},
// 'html[dir="rtl"] &': {
// textAlign: 'right' as 'right',
// },
},
'& code': {
padding: '2px 4px',
......@@ -164,28 +165,28 @@ const styles = (theme) => ({
fontSize: '16px',
lineHeight: '1.4em',
marginLeft: 0,
'html[dir="rtl"] &': {
marginRight: 0,
},
// 'html[dir="rtl"] &': {
// marginRight: 0,
// },
listStyleType: 'none' as 'none',
'& ul': {
'html[dir="ltr"] &': {
// 'html[dir="ltr"] &': {
paddingLeft: '0.8em',
},
'html[dir="rtl"] &': {
paddingRight: '0.8em',
},
// },
// 'html[dir="rtl"] &': {
// paddingRight: '0.8em',
// },
},
},
'& > ul': {
fontSize: '16px',
lineHeight: '1.4em',
'html[dir="ltr"] &': {
// 'html[dir="ltr"] &': {
marginLeft: '.125em',
},
'html[dir="rtl"] &': {
marginRight: '.125em',
},
// },
// 'html[dir="rtl"] &': {
// marginRight: '.125em',
// },
padding: 0,
},
'& a': {
......
......@@ -11,6 +11,7 @@ interface ICropChipsProps extends React.ClassAttributes<any> {
}
const styles = (theme) => ({
/* tslint:disable */
chipHolder: {
display: 'inline-block',
position: 'relative' as 'relative',
......@@ -18,7 +19,12 @@ const styles = (theme) => ({
},
chip: {
display: 'inline-block',
'html[dir="ltr"] &' : {
marginRight: theme.spacing.unit,
},
'html[dir="rtl"] &' : {
marginLeft: theme.spacing.unit,
},
padding: '.2em .5em',
position: 'relative' as 'relative',
top: '-.2em',
......@@ -28,6 +34,7 @@ const styles = (theme) => ({
color: 'Black',
fontWeight: 'bold' as 'bold',
},
/* tslint:enable */
});
const CropChips = ({crops, availableCrops, classes}: ICropChipsProps) => {
......
......@@ -90,6 +90,7 @@ class BasicInfoStep extends React.Component<ILoginContainerProps, any> {
valueField="code"
renderOptionLabel={ renderLicenseLabel }
singleColumn
style={ { wordBreak: 'break-all' } }
/>
<Field
name="language"
......
import * as React from 'react';
import { Field, reduxForm } from 'redux-form';
import { translate } from 'react-i18next';
import withStyles from '@material-ui/core/styles/withStyles';
import { DESCRIPTORLIST_FORM } from 'descriptors/constants';
import { TextField } from 'ui/common/text-field';
......@@ -11,10 +12,25 @@ import Validators from 'utilities/Validators';
import RadioSelection from 'ui/common/forms/RadioSelection';
import { saveDescriptorList } from 'descriptorlists/actions/editor';
/* tslint:disable */
const styles = (theme) => ({
cropRadio: {
'&:nth-child(n)': {
[theme.breakpoints.up('lg')]: {
flexBasis: '16%',
},
[theme.breakpoints.up('xl')]: {
flexBasis: '12%',
},
},
}
});
/* tslint:enable */
class DescriptorListForm extends React.Component<any, any> {
public render() {
const {error, handleSubmit, initialValues, partners, crops, t} = this.props;
const {error, handleSubmit, initialValues, partners, crops, t, classes} = this.props;
return (
<form onSubmit={ handleSubmit } className="p-20 m-20 even-row">
{ initialValues && initialValues.version && <div>Version: { initialValues.version }</div> }
......@@ -55,6 +71,7 @@ class DescriptorListForm extends React.Component<any, any> {
</Authorize>
<Field
className={ classes.cropRadio }
name="crop"
formLabel={ t('descriptorlists.public.common.crop') }
placeholder={ t('descriptorlists.public.c.form.maize') }
......@@ -115,8 +132,10 @@ class DescriptorListForm extends React.Component<any, any> {
}
}
export default translate()(reduxForm({
export default translate()(withStyles(styles)(
reduxForm({
enableReinitialize: true, // https://redux-form.com/7.1.0/examples/initializefromstate/
form: DESCRIPTORLIST_FORM,
onSubmit: (values, dispatch) => dispatch(saveDescriptorList(values)),
})(DescriptorListForm));
})(DescriptorListForm)),
);
......@@ -150,10 +150,10 @@ class DescriptorPicker extends React.Component<IDescriptorPickerProps, any> {
return (
<Grid container spacing={ 0 } className={ classes.container }>
<Grid item xs={ 12 } md={ 4 } lg={ 2 } className={ classes.leftPanel }>
<Grid item xs={ 12 } lg={ 2 } className={ classes.leftPanel }>
<DescriptorFilters initialValues={ matchingDescriptors && matchingDescriptors.filter || {} } onSubmit={ this.applyFilters }/>
</Grid>
<Grid item xs={ 12 } md={ 4 } lg={ 5 } className={ classes.grayBackground }>
<Grid item xs={ 12 } lg={ 5 } className={ classes.grayBackground }>
{ matchingDescriptors && matchingDescriptors.content && matchingDescriptors.content.length < 2 ?
<div className={ classes.fake }/> :
<PaginationComponent
......@@ -177,7 +177,7 @@ class DescriptorPicker extends React.Component<IDescriptorPickerProps, any> {
/>
}
</Grid>
<Grid item xs={ 12 } md={ 4 } lg={ 5 } className={ `${ classnames({ [classes.greenBackground]: currentDescriptors.length > 0 }) } even-row` }>
<Grid item xs={ 12 } lg={ 5 } className={ `${ classnames({ [classes.greenBackground]: currentDescriptors.length > 0 }) } even-row` }>
<Grid container item spacing={ 0 }>
<h4 className="font-bold pt-20 pl-20">
{ currentDescriptors.length } { currentDescriptors.length > 1 ?
......
......@@ -49,19 +49,16 @@ class BooleanDimensionFormExtraInternal extends React.Component<IBooleanFilterIn
value="1"
control={ <Radio /> }
label={ t('common:label.true') }
className="form-control-label-rtl"
/>
<FormControlLabel
value="2"
control={ <Radio /> }
label={ t('common:label.false') }
className="form-control-label-rtl"
/>
<FormControlLabel
value="3"
control={ <Radio /> }
label={ t('common:label.either') }
className="form-control-label-rtl"
/>
</RadioGroup>
</FormControl>
......
......@@ -37,19 +37,16 @@ const ExecutionTypeSelector = ({input, meta, t, ...rest}) => {
value="COUNT"
control={ <Radio /> }
label={ t('kpi.admin.c.execution.type.COUNT') }
className="form-control-label-rtl"
/>
<FormControlLabel
value="AVERAGE"
control={ <Radio /> }
label={ t('kpi.admin.c.execution.type.AVERAGE') }
className="form-control-label-rtl"
/>
<FormControlLabel
value="SUM"
control={ <Radio /> }
label={ t('kpi.admin.c.execution.type.SUM') }
className="form-control-label-rtl"
/>
</RadioGroup>
</FormControl>
......
......@@ -25,6 +25,7 @@ interface ISelectFaoInstituteInternal extends React.ClassAttributes<any> {
}
class SelectFaoInstituteInternal extends React.Component<ISelectFaoInstituteInternal, any> {
public updateMenuPosition = null;
protected handleInputChange = (event) => {
this.setState({searchText: event.target.value});
......@@ -34,6 +35,7 @@ class SelectFaoInstituteInternal extends React.Component<ISelectFaoInstituteInte
}
private doAutocomplete = debounce((value) => {
this.props.autocompleteWiewsTerm(value).then((suggestions) => {
this.updateMenuPosition();
this.setState({suggestions});
});
}, 1000);
......@@ -130,6 +132,7 @@ class SelectFaoInstituteInternal extends React.Component<ISelectFaoInstituteInte
anchorEl={ this.state.anchorEl }
open={ this.state.open }
onClose={ this.handleRequestClose }
action={ (actions) => this.updateMenuPosition = actions.updatePosition }
>
<MenuItem>
<TextField
......
......@@ -26,7 +26,6 @@ const PurposeTypeRadioGroup = ({input, meta, classes, formLabel, t, ...rest}) =>
value={ purposeType.value }
label={ t(purposeType.label) }
control={ <Radio/> }
className="form-control-label-rtl"
/>
))
}
......
......@@ -65,7 +65,6 @@ const renderRadioGroup = translate()(({input, meta, t, classes}) => {
value={ role }
label={ t(`subsets.common.creators.role.${role}`) }
control={ <Radio/> }
className="form-control-label-rtl"
/>
)) }
</RadioGroup>
......
......@@ -13,20 +13,16 @@ const styles = () => ({
inProgress: {
color: '#ed9506',
},
status: {
fontSize: '1rem',
marginRight: '6px',
},
});
const DashboardCardStatus = ({item, t, classes}: {item: any, t; any, classes: any} & React.ClassAttributes<any>) => {
switch (item.state) {
case PublishState.PUBLISHED:
return <b className={ `${classes.status} ${classes.published}` }>{ t('status.published') }</b>;
return <b className={ `mr-5 ${classes.published}` }>{ t('status.published') }</b>;
case PublishState.REVIEWING:
return <b className={ `${classes.status} ${classes.inReview}` }>{ t('status.inReview') }</b>;
return <b className={ `mr-5 ${classes.inReview}` }>{ t('status.inReview') }</b>;
default:
return <b className={ `${classes.status} ${classes.inProgress}` }>{ t('status.inProgress') }</b>;
return <b className={ `mr-5 ${classes.inProgress}` }>{ t('status.inProgress') }</b>;
}
};
......
......@@ -5,7 +5,6 @@ import Checkbox from '@material-ui/core/Checkbox';
const ReduxCheckbox = ({input: {value, onChange}, label = null, style = {height: '40px'}, ...rest}) => (
<FormControlLabel
style={ style }
className="form-control-label-rtl"
control={
<Checkbox
checked={ !!value && value !== 'false' }
......
......@@ -103,7 +103,7 @@ class CSVConfiguration extends React.Component<ICSVConfigurationProps, any> {
control={
<Checkbox onChange={ this.handleAutodetect } />
}
className="form-control-label-rtl"
className="mr-1rem"
/>
</FormControl>
</Grid>
......@@ -118,34 +118,35 @@ class CSVConfiguration extends React.Component<ICSVConfigurationProps, any> {
value="tab"
label={ t('common:csv.tab') }
control={ <Radio/> }
className="form-control-label-rtl"
className="mr-1rem"
/>
<FormControlLabel
value="comma"
label={ t('common:csv.comma') }
control={ <Radio/> }
className="form-control-label-rtl"
className="mr-1rem"
/>
<FormControlLabel
value="semicolon"
label={ t('common:csv.semicolon') }
control={ <Radio/> }
className="form-control-label-rtl"
className="mr-1rem"
/>
<FormControlLabel
value="space"
label={ t('common:csv.space') }
control={ <Radio/> }
className="form-control-label-rtl"
className="mr-1rem"
/>
<FormControlLabel
value="other"
label={ t('common:csv.other') }
control={ <Radio/> }
className="form-control-label-rtl"
className="mr-1rem"
/>
<FormControlLabel
label=""
className="pl-1rem"
control={ <Input placeholder={ t('common:csv.typeYourSeparator') } onBlur={ this.handleInputSeparator } /> }
/>
</RadioGroup>
......
......@@ -113,10 +113,10 @@ class FiltersBlock extends React.Component<any> {
});
public render() {
const {classes, children, t, title} = this.props;
const {classes, children, t, title, className} = this.props;
return (
<div className={ classes.filtersBlock }>
<div className={ `${classes.filtersBlock} ${className}` }>
<ExpandFiltersComponent title={ title || 'Filters' }>
<form onSubmit={ this.processSubmit }>
<div className={ `pt-20 pb-20 pl-20 ${ classes.stickyButtonContainer }` }>
......
......@@ -79,7 +79,6 @@ class LicenceFilterInternal extends React.Component<ILicenceFilterInternalProps>
<FormControlLabel
key={ license.code }
value={ license.code }
className="form-control-label-rtl"
label={ (
<div><b>{ license.code }</b>
{ license.url &&
......
......@@ -351,11 +351,10 @@ class InternalStringArrField extends React.Component<IStringArrFilterInternal &
key={ valueField ? `${ key[valueField] }` : `${ key }` }
style={
(document && document.dir === 'rtl') ?
{ paddingRight: `${tree ? (tree.get(key) * 20) : 0}px`, marginLeft: 0 } :
{ paddingLeft: `${tree ? (tree.get(key) * 20) : 0}px`, marginRight: 0 }
{ paddingRight: `${tree ? (tree.get(key) * 20) : 0}px` } :
{ paddingLeft: `${tree ? (tree.get(key) * 20) : 0}px` }
}
classes={ {label: 'full-width', root: 'mr-0'} }
className="form-control-label-rtl"
label={
<span className="full-width" style={ {display: 'flex', justifyContent: 'space-between'} }>
{ `${ t(options[key]) || (labelField ? key[labelField] : key) }` }
......
......@@ -21,13 +21,11 @@ const BooleanRadioGroup = ({input, meta, classes, formLabel, labelTrue, labelFal
value="true"
label={ labelTrue }
control={ <Radio/> }
className="form-control-label-rtl"
/>
<FormControlLabel
value="false"
label={ labelFalse }
control={ <Radio/> }
className="form-control-label-rtl"
/>
</RadioGroup>
</FormControl>
......
......@@ -67,7 +67,7 @@ const CheckboxSelection = ({formLabel, singleColumn = false, options, renderOpti
onChange={ (event, value) => handleCheckboxChange(fields,valueField ? option[valueField] : option) } // tslint:disable-line
/>
}
className={ `form-control-label-rtl ${classes.label}` }
className={ classes.label }
/>
))
}
......
......@@ -15,6 +15,12 @@ const styles = (theme) =>({
justifyContent: 'flex-start' as 'flex-start',
'& > label': {
flexBasis: '12%',
'html[dir="ltr"] &' : {
marginRight: '16px',
},
'html[dir="rtl"] &' : {
marginLeft: '16px',
},
[theme.breakpoints.down('md')]: {
flexBasis: '24%',
},
......@@ -51,7 +57,6 @@ const RadioSelection = ({formLabel, singleColumn = false, options, renderOptionL
value={ valueField ? option[valueField] : option }
label={ renderOptionLabel ? renderOptionLabel(option) : valueField ? option[valueField] : option }
control={ <Radio/> }
className="form-control-label-rtl"
classes={ {label: classes.label} }
{ ...rest }
/>
......
......@@ -16,7 +16,6 @@ const renderToggler = ({input, falseIsNull = false, label, meta, t, ...rest}: {
<FormControlLabel
control={ <Switch checked={ input.value } onChange={ onChange } /> }
label={ t(label) }
className="form-control-label-rtl"
/>
);
};
......
......@@ -47,6 +47,7 @@ const styles = {
height: '100%',
position: 'relative' as 'relative',
overflowX: 'visible' as 'visible',
flexShrink: 0,
},
menuPosition: {
right: 0,
......
......@@ -147,6 +147,18 @@ const styleSheet = (theme) => ({
justifyContent: 'flex-end' as 'flex-end',
},
},
navWrapperCompact: {
'html[dir="ltr"] &' : {
[theme.breakpoints.down(1460)]: {
paddingLeft: 0,
},
},
'html[dir="rtl"] &' : {
[theme.breakpoints.down(1460)]: {
paddingRight: 0,
},
},
},
headerMargin: {
marginBottom: '83px',
[theme.breakpoints.down('md')]: {
......@@ -215,6 +227,8 @@ class AdminHeader extends React.Component<IHeaderProps | any, any> {
const {classes, t, menuItems, location, root, title, theme, customLogo} = this.props;
const menuTheme = theme || MenuThemes.white;
const headerMenuLength = menuItems.filter((item) => item.inHeader !== false).length;
return (
<div className={ `header-bar ${ classes.headerMargin }` }>
<AppBar position="fixed" className={ classes.headerRoot } style={ {backgroundColor: `${menuTheme.appBar}`} }>
......@@ -248,7 +262,7 @@ class AdminHeader extends React.Component<IHeaderProps | any, any> {
</Link>
{ title && <Link to={ root }><div className={ classes.admin } style={ {color: menuTheme.appText} }>{ t(title) }</div></Link> }
</div>
<div className={ `${classes.flex} ${this.props.classes.navWrapper}` }>
<div className={ `${classes.flex} ${this.props.classes.navWrapper} ${headerMenuLength > 5 ? classes.navWrapperCompact : ''}` }>
<MenuBar t={ t } location={ location } menuItems={ menuItems } theme={ menuTheme }/>
{ this.renderLogin([ROLE_USER, ROLE_ADMINISTRATOR]) }
<LanguageList location={ location } color={ menuTheme.langList } theme={ menuTheme }/>
......
......@@ -53,7 +53,7 @@ const styles = (theme) => ({
}
},
drawerAlwaysCollapsible: {
maxWidth: '90%',
maxWidth: '90%!important',
position: 'fixed' as 'fixed',
zIndex: 1250,
},
......@@ -77,8 +77,10 @@ const styles = (theme) => ({
},
sidebar: {
whiteSpace: 'nowrap' as 'nowrap',
minWidth: '320px',
width: 'auto',
minWidth: '360px',
'html[dir="rtl"] &' : {
minWidth: '420px',
},
height: '100%',
display: 'flex' as 'flex',
flexDirection: 'column' as 'column',
......@@ -95,6 +97,9 @@ const styles = (theme) => ({
}),
cursor: 'e-resize',
minWidth: theme.spacing.unit * 3,
'html[dir="rtl"] &' : {
minWidth: theme.spacing.unit * 3,
},
[theme.breakpoints.up('sm')]: {
maxWidth: theme.spacing.unit * 9,
},
......
......@@ -16,6 +16,17 @@ const theme = (dir) => createMuiTheme({
marginBottom: '0.71rem', // 10px
},
},
MuiFormControlLabel: {
root: {
'html[dir="ltr"] &' : {
marginRight: 0,
},
'html[dir="rtl"] &' : {
marginRight: '-14px',
marginLeft: 0,
},
}
},
MuiTypography: {
body2: {
color: 'initial',
......
......@@ -3,6 +3,7 @@ import { connect } from 'react-redux';