Skip to content

Commit

Permalink
Merge pull request #94 from glorious-codes/react_fetcher_fix
Browse files Browse the repository at this point in the history
Improve Fetcher component for React
  • Loading branch information
rafaelcamargo committed Feb 28, 2021
2 parents 158b76a + a7fe7ab commit 885ef9a
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 64 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@glorious/taslonic",
"version": "1.1.3",
"version": "1.1.4",
"description": "A glorious UI library available for React and Vue",
"files": [
"react/**",
Expand Down
140 changes: 79 additions & 61 deletions src/react/components/fetcher/fetcher.js
@@ -1,71 +1,89 @@
import '@base/styles/fetcher.styl';
import React, { useState, useEffect } from 'react';
import React, { Component } from 'react';
import { Loader } from '@react/components/loader/loader';
import { Banner } from '@react/components/banner/banner';
import fetcherService from '@base/services/fetcher/fetcher';

export const Fetcher = ({
onFetch,
onFetchSuccess,
onFetchError,
fetchErrorMessage,
children,
...rest
}) => {
let fetcher;
const [fetching, setFetching] = useState();
const [fetchFailed, setFetchFailed] = useState();
const [banner, setBanner] = useState();
const handleFetchError = err => {
setBanner({
message: getBannerMessage(),
onTriggerClick: () => fetcher.fetch()
export class Fetcher extends Component {
constructor(props){
super(props);
this.state = {};
}

handleFetchError(err){
this.setBanner({
message: this.getBannerMessage(),
onTriggerClick: () => this.state.fetcher.fetch()
});
handleCallbackProp(onFetchError, err);
};
const getBannerMessage = () => {
return fetchErrorMessage || fetcherService.getMessage('FETCH_ERROR_MESSAGE');
};
const handleProcessChange = ({ isFetching, fetchFailed }) => {
setFetching(isFetching);
setFetchFailed(fetchFailed);
if(isFetching) setBanner(null);
};
const handleCallbackProp = (callback, data) => callback && callback(data);
const handleLoader = () => {
if(fetching) return <Loader data-form-loader />;
};
const handleBanner = () => {
if(banner)
return (
<Banner
theme="danger"
triggerText="Retry"
onTriggerClick={banner.onTriggerClick}
onClose={() => setBanner(null)}
data-fetcher-error-banner
>
{banner.message}
</Banner>
);
};
this.handleCallbackProp(this.props.onFetchError, err);
}

handleProcessChange({ isFetching, fetchFailed }){
this.setFetching(isFetching);
this.setFetchFailed(fetchFailed);
if(isFetching) this.setBanner(null);
}

handleCallbackProp(callback, data){
callback && callback(data);
}

setBanner(banner){
this.setState({ banner });
}

setFetching(fetching){
this.setState({ fetching });
}

useEffect(() => {
fetcher = fetcherService.build({
onFetch: () => handleCallbackProp(onFetch),
onFetchSuccess: response => handleCallbackProp(onFetchSuccess, response),
onFetchError: err => handleFetchError(err),
onProcessChange: handleProcessChange
setFetchFailed(fetchFailed){
this.setState({ fetchFailed });
}

getBannerMessage(){
return this.props.fetchErrorMessage || fetcherService.getMessage('FETCH_ERROR_MESSAGE');
}

componentDidMount(){
const fetcher = fetcherService.build({
onFetch: () => this.props.onFetch(),
onFetchSuccess: response => this.handleCallbackProp(this.props.onFetchSuccess, response),
onFetchError: err => this.handleFetchError(err),
onProcessChange: process => this.handleProcessChange(process)
});
}, []);
this.setState({ fetcher });
}

render(){
const { fetching, fetchFailed, banner } = this.state;

return (
<div className={fetcherService.buildCssClasses({ fetching, fetchFailed })} {...rest}>
{ handleLoader(fetching) }
{ handleBanner(banner) }
<div className="t-fetcher-content" aria-live="polite" aria-busy={fetching} data-fetcher-content>
{ children }
return (
<div className={fetcherService.buildCssClasses({ fetching, fetchFailed })}>
{ handleLoader(fetching) }
{ handleBanner(banner, () => this.setBanner(null)) }
<div className="t-fetcher-content" aria-live="polite" aria-busy={fetching} data-fetcher-content>
{ this.props.children }
</div>
</div>
</div>
);
};
);
}
}

function handleLoader(fetching){
if(fetching) return <Loader data-form-loader />;
}

function handleBanner(banner, onBannerClose){
if(banner)
return (
<Banner
theme="danger"
triggerText="Retry"
onTriggerClick={banner.onTriggerClick}
onClose={onBannerClose}
data-fetcher-error-banner
>
{banner.message}
</Banner>
);
}

0 comments on commit 885ef9a

Please sign in to comment.