From 8980bfa610d572e4e02bbdec361952a9e8881088 Mon Sep 17 00:00:00 2001 From: Alexandru Munteanu <alexandru.munt@gmail.com> Date: Thu, 16 Aug 2018 12:47:23 +0300 Subject: [PATCH] feat(styleguide): add activity indicator --- packages/component-faraday-ui/src/AppBar.md | 25 +++- .../src/AutosaveIndicator.js | 114 ++++++++++++++++++ .../src/AutosaveIndicator.md | 33 +++++ packages/component-faraday-ui/src/Text.js | 6 + 4 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 packages/component-faraday-ui/src/AutosaveIndicator.js create mode 100644 packages/component-faraday-ui/src/AutosaveIndicator.md diff --git a/packages/component-faraday-ui/src/AppBar.md b/packages/component-faraday-ui/src/AppBar.md index 7348050a0..998fc578b 100644 --- a/packages/component-faraday-ui/src/AppBar.md +++ b/packages/component-faraday-ui/src/AppBar.md @@ -10,6 +10,10 @@ const currentUser = { } }; +const autosave = { + isFetching: true +}; + const HindawiLogo = () => <Logo onClick={() => console.log('Hindawi best publish!')} title="Hindawi" @@ -17,12 +21,15 @@ const HindawiLogo = () => <Logo />; const MenuComponent = () => <AppBarMenu - currentUser={currentUser} - goTo={path => console.log(`navigating to ${path}`)} - logout={() => console.log('logging out')} + currentUser={currentUser} + goTo={path => console.log(`navigating to ${path}`)} + logout={() => console.log('logging out')} />; -const AutosaveComponent = () => <div>AUTOSAVE</div>; +const AutosaveComponent = () => <AutosaveIndicator + isVisible + autosave={autosave} + />; <AppBar autosave={AutosaveComponent} @@ -54,13 +61,21 @@ const HindawiLogo = () => <Logo src="https://upload.wikimedia.org/wikipedia/en/thumb/c/ca/Hindawi.svg/1200px-Hindawi.svg.png" />; +const autosave = { + isFetching: false, + lastUpdate: new Date(), +}; + const MenuComponent = () => <AppBarMenu currentUser={currentUser} goTo={path => console.log(`navigating to ${path}`)} logout={() => console.log('logging out')} />; -const AutosaveComponent = () => <div>AUTOSAVE</div>; +const AutosaveComponent = () => <AutosaveIndicator + isVisible + autosave={autosave} + />; <AppBar autosave={AutosaveComponent} diff --git a/packages/component-faraday-ui/src/AutosaveIndicator.js b/packages/component-faraday-ui/src/AutosaveIndicator.js new file mode 100644 index 000000000..17e7be261 --- /dev/null +++ b/packages/component-faraday-ui/src/AutosaveIndicator.js @@ -0,0 +1,114 @@ +/* eslint-disable react/prefer-stateless-function */ + +import React, { Component } from 'react' +import { isEqual } from 'lodash' +import styled from 'styled-components' +import { th } from '@pubsweet/ui-toolkit' +import { Icon, Spinner } from '@pubsweet/ui' +import { compose, setDisplayName, withStateHandlers } from 'recompose' + +import Text from './Text' + +class AutosaveIndicator extends Component { + constructor(props) { + super(props) + this.timer = null + } + + componentDidMount() { + this.setTimer() + } + + componentWillReceiveProps({ autosave: nextAutosave }) { + const { autosave, toggleVisible } = this.props + if (!isEqual(autosave, nextAutosave)) { + toggleVisible() + this.setTimer() + } + } + + setTimer = () => { + const { toggleVisible, delay = 2000 } = this.props + if (this.timer) { + clearTimeout(this.timer) + } + this.timer = setTimeout(toggleVisible, delay) + } + + render() { + const { + isVisible, + successText = 'Changes saved', + errorText = 'Changes not saved', + progressText = 'Saving changes...', + autosave: { isFetching, error, lastUpdate }, + } = this.props + return isVisible ? ( + <Root className="autosave-indicator"> + {isFetching && ( + <AutoSaveContainer> + <Spinner icon="loader" size={2} /> + <Text>{progressText}</Text> + </AutoSaveContainer> + )} + + {!isFetching && + lastUpdate && ( + <AutoSaveContainer> + <IconContainer> + <Icon primary size={2}> + check-circle + </Icon> + </IconContainer> + <Text>{successText}</Text> + </AutoSaveContainer> + )} + {!isFetching && + error && ( + <AutoSaveContainer> + <IconContainer> + <Icon error size={2}> + alert-triangle + </Icon> + </IconContainer> + <Text error title={error}> + {errorText} + </Text> + </AutoSaveContainer> + )} + </Root> + ) : ( + <span /> + ) + } +} + +export default compose( + withStateHandlers( + { isVisible: true }, + { + toggleVisible: ({ isVisible }, props) => () => ({ + isVisible: !isVisible, + }), + }, + ), + setDisplayName('AutosaveIndicator'), +)(AutosaveIndicator) + +// #region styles +const Root = styled.div` + align-items: center; + display: flex; + justify-content: flex-end; +` +const AutoSaveContainer = styled.div` + align-items: center; + display: flex; + padding: ${th('gridUnit')}; +` +const IconContainer = styled.div` + align-items: center; + display: flex; + justify-content: center; +` +// #endregion diff --git a/packages/component-faraday-ui/src/AutosaveIndicator.md b/packages/component-faraday-ui/src/AutosaveIndicator.md new file mode 100644 index 000000000..4c7f96553 --- /dev/null +++ b/packages/component-faraday-ui/src/AutosaveIndicator.md @@ -0,0 +1,33 @@ +Display the status of the form (Saving in progress, Saved or Error while saving) + +Saving in progress. The indicator will be hidden after a certain delay. + +```js +const autosave = { + isFetching: true +}; + +<AutosaveIndicator delay={4000} autosave={autosave} /> +``` + +Changes saved. + +```js +const autosave = { + isFetching: false, + lastUpdate: new Date(), +}; + +<AutosaveIndicator autosave={autosave} /> +``` + +Error saving changes. + +```js +const autosave = { + isFetching: false, + error: 'Something went wrong...', +}; + +<AutosaveIndicator autosave={autosave} /> +``` \ No newline at end of file diff --git a/packages/component-faraday-ui/src/Text.js b/packages/component-faraday-ui/src/Text.js index a512f96ff..d36c9b262 100644 --- a/packages/component-faraday-ui/src/Text.js +++ b/packages/component-faraday-ui/src/Text.js @@ -9,6 +9,12 @@ const textHelper = props => { font-family: ${th('fontReading')}; ` } + if (has(props, 'error')) { + return css` + color: ${th('colorError')}; + font-family: ${th('fontReading')}; + ` + } if (has(props, 'customId')) { return css` color: ${th('colorPrimary')}; -- GitLab