Migrate plugin to styled compo

This commit is contained in:
soupette 2019-09-11 11:00:40 +02:00
parent ff184ec200
commit ce2575151e
9 changed files with 137 additions and 149 deletions

View File

@ -20,21 +20,24 @@ function ListHeader({ changeSort, sort }) {
'', '',
'', '',
]; ];
console.log(sort);
const handleChangeSort = name => { const handleChangeSort = name => {
if (sort === name) { if (sort === `${name}:ASC`) {
changeSort(`-${name}`); changeSort(`${name}:DESC`);
} else if (sort === `-${name}`) { } else if (sort === `${name}:DESC`) {
changeSort('hash'); changeSort('hash:ASC');
} else if (name === 'updated' || name === 'related') { } else if (name === 'updated' || name === 'related') {
changeSort('hash'); changeSort('hash:ASC');
} else { } else {
changeSort(name); changeSort(`${name}:ASC`);
} }
}; };
const shouldDisplaySort = title => const shouldDisplaySort = title =>
(sort === title && 'icon') || (sort === `-${title}` && 'iconDesc') || ''; (sort === `${title}:ASC` && 'icon') ||
(sort === `${title}:DESC` && 'iconDesc') ||
'';
return ( return (
<StyledLi> <StyledLi>

View File

@ -0,0 +1,82 @@
import styled, { css, keyframes } from 'styled-components';
const Label = styled.label`
position: relative;
height: 146px;
width: 100%;
padding-top: 28px;
border: 2px dashed #e3e9f3;
border-radius: 2px;
text-align: center;
> input {
display: none;
}
.icon {
width: 82px;
path {
fill: ${({ showLoader }) => (showLoader ? '#729BEF' : '#ccd0da')};
transition: fill 0.3s ease;
}
}
.isDraging {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.underline {
color: #1c5de7;
text-decoration: underline;
cursor: pointer;
}
&:hover {
cursor: pointer;
}
${({ isDraging }) => {
if (isDraging) {
return css`
background-color: rgba(28, 93, 231, 0.01) !important;
border: 2px dashed rgba(28, 93, 231, 0.1) !important;
`;
}
}}
${({ showLoader }) => {
if (showLoader) {
return css`
-webkit-animation: ${smoothBlink('transparent', 'rgba(28,93,231,0.05)')}
2s linear infinite;
-moz-animation: ${smoothBlink('transparent', 'rgba(28,93,231,0.05)')} 2s
linear infinite;
-o-animation: ${smoothBlink('transparent', 'rgba(28,93,231,0.05)')} 2s
linear infinite;
animation: ${smoothBlink('transparent', 'rgba(28,93,231,0.05)')} 2s
linear infinite;
`;
}
}}
`;
const smoothBlink = (firstColor, secondColor) => keyframes`
0% {
fill: ${firstColor};
background-color: ${firstColor};
}
26% {
fill: ${secondColor};
background-color: ${secondColor};
}
76% {
fill: ${firstColor};
background-color: ${firstColor};
}
`;
export default Label;

View File

@ -0,0 +1,14 @@
import styled from 'styled-components';
const P = styled.p`
margin-top: 10px;
text-align: center;
font-size: 13px;
color: #9ea7b8;
u {
color: #1c5de7;
}
`;
export default P;

View File

@ -7,9 +7,8 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import cn from 'classnames'; import Label from './Label';
import P from './P';
import styles from './styles.scss';
/* eslint-disable react/no-string-refs */ /* eslint-disable react/no-string-refs */
/* eslint-disable jsx-a11y/label-has-for */ /* eslint-disable jsx-a11y/label-has-for */
@ -37,17 +36,14 @@ class PluginInputFile extends React.PureComponent {
const { isDraging } = this.state; const { isDraging } = this.state;
const link = ( const link = (
<FormattedMessage id="upload.PluginInputFile.link"> <FormattedMessage id="upload.PluginInputFile.link">
{message => <span className={styles.underline}>{message}</span>} {message => <span className="underline">{message}</span>}
</FormattedMessage> </FormattedMessage>
); );
return ( return (
<label <Label
className={cn( showLoader={showLoader}
styles.pluginInputFile, isDraging={isDraging}
isDraging && styles.pluginInputFileHover,
showLoader && styles.quadrat
)}
onDragEnter={this.handleDragEnter} onDragEnter={this.handleDragEnter}
onDragOver={e => { onDragOver={e => {
e.preventDefault(); e.preventDefault();
@ -56,7 +52,7 @@ class PluginInputFile extends React.PureComponent {
onDrop={this.handleDrop} onDrop={this.handleDrop}
> >
<svg <svg
className={styles.icon} className="icon"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 104.40317 83.13328" viewBox="0 0 104.40317 83.13328"
> >
@ -115,7 +111,7 @@ class PluginInputFile extends React.PureComponent {
/> />
</g> </g>
</svg> </svg>
<p className={styles.textWrapper}> <P>
{!showLoader && ( {!showLoader && (
<FormattedMessage <FormattedMessage
id="upload.PluginInputFile.text" id="upload.PluginInputFile.text"
@ -125,13 +121,10 @@ class PluginInputFile extends React.PureComponent {
{showLoader && ( {showLoader && (
<FormattedMessage id="upload.PluginInputFile.loading" /> <FormattedMessage id="upload.PluginInputFile.loading" />
)} )}
</p> </P>
<div <div onDragLeave={this.handleDragLeave} className="isDraging" />
onDragLeave={this.handleDragLeave}
className={cn(isDraging && styles.isDraging)}
/>
<input multiple name={name} onChange={this.handleChange} type="file" /> <input multiple name={name} onChange={this.handleChange} type="file" />
</label> </Label>
); );
} }
} }

View File

@ -1,102 +0,0 @@
.isDraging {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.pluginInputFile {
position: relative;
height: 146px;
width: 100%;
padding-top: 28px;
border: 2px dashed #E3E9F3;
border-radius: 2px;
text-align: center;
> input {
display: none;
}
.icon{
width: 82px;
path{
fill: #CCD0DA;
transition: fill .3s ease;
}
}
&:hover{
cursor: pointer;
}
}
.textWrapper {
margin-top: 10px;
text-align: center;
font-size: 13px;
color: #9EA7B8;
u {
color: #1C5DE7;
}
}
.pluginInputFileHover {
background-color: rgba(28,93,231,0.01) !important;
border: 2px dashed rgba(28,93,231,0.10) !important;
}
.underline {
color: #1C5DE7;
text-decoration: underline;
cursor: pointer;
}
@mixin smoothBlink($firstColor, $secondColor) {
@-webkit-keyframes blink {
0% {
fill: $firstColor;
background-color: $firstColor;
}
26% {
fill: $secondColor;
background-color: $secondColor;
}
76% {
fill: $firstColor;
background-color: $firstColor;
}
}
@keyframes blink {
0% {
fill: $firstColor;
background-color: $firstColor;
}
26% {
fill: $secondColor;
background-color: $secondColor;
}
76% {
fill: $firstColor;
background-color: $firstColor;
}
}
-webkit-animation: blink 2s linear infinite;
-moz-animation: blink 2s linear infinite;
-o-animation: blink 2s linear infinite;
animation: blink 2s linear infinite;
}
.quadrat {
.icon{
path {
fill: #729BEF;
}
}
@include smoothBlink(transparent, rgba(28, 93, 231, 0.05));
}

View File

@ -1,12 +1,16 @@
.homePageUpload { import styled from 'styled-components';
padding-right: 20px;
font-family: Lato !important;
}
.entriesWrapper { const EntriesWrapper = styled.div`
display: flex; display: flex;
height: 43px; height: 43px;
width: 100%; width: 100%;
padding-top: 16px; padding-top: 16px;
justify-content: space-between; justify-content: space-between;
} `;
const Wrapper = styled.div`
padding-right: 20px;
font-family: Lato !important;
`;
export { EntriesWrapper, Wrapper };

View File

@ -7,7 +7,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
// import { createStructuredSelector } from 'reselect';
import { injectIntl } from 'react-intl'; import { injectIntl } from 'react-intl';
import { bindActionCreators, compose } from 'redux'; import { bindActionCreators, compose } from 'redux';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
@ -26,8 +25,8 @@ import pluginId from '../../pluginId';
import EntriesNumber from '../../components/EntriesNumber'; import EntriesNumber from '../../components/EntriesNumber';
import List from '../../components/List'; import List from '../../components/List';
import PluginInputFile from '../../components/PluginInputFile'; import PluginInputFile from '../../components/PluginInputFile';
import { EntriesWrapper, Wrapper } from './components';
// Actions
import { import {
changeParams, changeParams,
deleteData, deleteData,
@ -36,13 +35,7 @@ import {
onSearch, onSearch,
setParams, setParams,
} from './actions'; } from './actions';
// Selectors
import selectHomePage from './selectors'; import selectHomePage from './selectors';
// Styles
import styles from './styles.scss';
import reducer from './reducer'; import reducer from './reducer';
import saga from './saga'; import saga from './saga';
@ -120,7 +113,7 @@ export class HomePage extends React.Component {
render() { render() {
return ( return (
<ContainerFluid> <ContainerFluid>
<div className={styles.homePageUpload}> <Wrapper>
<PluginHeader <PluginHeader
title={{ title={{
id: 'upload.HomePage.title', id: 'upload.HomePage.title',
@ -130,13 +123,13 @@ export class HomePage extends React.Component {
}} }}
overrideRendering={this.renderInputSearch} overrideRendering={this.renderInputSearch}
/> />
</div> </Wrapper>
<PluginInputFile <PluginInputFile
name="files" name="files"
onDrop={this.props.onDrop} onDrop={this.props.onDrop}
showLoader={this.props.uploadFilesLoading} showLoader={this.props.uploadFilesLoading}
/> />
<div className={styles.entriesWrapper}> <EntriesWrapper>
<div> <div>
{/* NOTE: Prepare for bulk actions} {/* NOTE: Prepare for bulk actions}
<InputSelect <InputSelect
@ -148,7 +141,7 @@ export class HomePage extends React.Component {
*/} */}
</div> </div>
<EntriesNumber number={this.props.entriesNumber} /> <EntriesNumber number={this.props.entriesNumber} />
</div> </EntriesWrapper>
<List <List
data={this.props.uploadedFiles} data={this.props.uploadedFiles}
changeSort={this.changeSort} changeSort={this.changeSort}

View File

@ -26,7 +26,7 @@ const initialState = fromJS({
search: '', search: '',
uploadedFiles: List([]), uploadedFiles: List([]),
params: Map({ params: Map({
_sort: 'hash', _sort: 'hash:ASC',
_limit: 10, _limit: 10,
_page: 1, _page: 1,
}), }),
@ -37,10 +37,11 @@ function homePageReducer(state = initialState, action) {
case CHANGE_PARAMS: case CHANGE_PARAMS:
return state.updateIn(action.keys, () => action.value); return state.updateIn(action.keys, () => action.value);
case DELETE_SUCCESS: case DELETE_SUCCESS:
return state.update('deleteSuccess', (v) => v = !v); return state.update('deleteSuccess', v => (v = !v));
case DROP_SUCCESS: case DROP_SUCCESS:
return state return state.update('uploadedFiles', list =>
.update('uploadedFiles', (list) => List(action.newFiles).concat(list)); List(action.newFiles).concat(list)
);
case GET_DATA_SUCCESS: case GET_DATA_SUCCESS:
return state return state
.update('uploadedFiles', () => List(action.data)) .update('uploadedFiles', () => List(action.data))