import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { get } from 'lodash';
import jobPropTypes from '../Jobs/components/Job/jobPropTypes';
import jobLogPropTypes from '../JobLogs/jobLogPropTypes';
import {
PROCESSING_IN_PROGRESS,
PROCESSING_FINISHED,
PARSING_IN_PROGRESS,
} from '../Jobs/jobStatuses';
import { DataFetcherContextProvider } from './DataFetcherContext';
import css from 'DataFetcher.css';
const DEFAULT_UPDATE_INTERVAL = 5000;
class DataFetcher extends Component {
static manifest = Object.freeze({
jobs: {
type: 'okapi',
path: `metadata-provider/jobExecutions?query=(status=("${PROCESSING_IN_PROGRESS}" OR "${PROCESSING_FINISHED}" OR "${PARSING_IN_PROGRESS}"))`,
accumulate: true,
throwErrors: false,
},
logs: {
type: 'okapi',
path: 'metadata-provider/logs?landingPage=true',
accumulate: true,
throwErrors: false,
},
});
static propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]).isRequired,
resources: PropTypes.shape({
jobs: PropTypes.shape({
records: PropTypes.arrayOf(
PropTypes.shape({
jobExecutionDtos: PropTypes.arrayOf(jobPropTypes).isRequired,
}),
).isRequired,
}),
logs: PropTypes.shape({
records: PropTypes.arrayOf(
PropTypes.shape({
logs: PropTypes.arrayOf(jobLogPropTypes).isRequired,
}),
).isRequired,
}),
}).isRequired,
updateInterval: PropTypes.number,
};
static defaultProps = {
updateInterval: DEFAULT_UPDATE_INTERVAL,
};
state = {
contextData: {},
};
constructor(){
super();
}
componentDidMount() {
this.setInitialState();
this.getResourcesData();
this.updateResourcesData();
}
componentWillUnmount() {
clearInterval(this.intervalId);
}
render() {
const { children } = this.props;
const { contextData } = this.state;
return (
<DataFetcherContextProvider value={contextData}>
{children}
</DataFetcherContextProvider>
);
}
updateResourcesData() {
const { updateInterval } = this.props;
this.intervalId = setInterval(this.getResourcesData, updateInterval);
}
setInitialState() {
const { mutator } = this.props;
const initialContextData = {};
Object.keys(mutator)
.forEach(resourceName => {
initialContextData[resourceName] = {
hasLoaded: false,
};
});
this.setState({
contextData: initialContextData,
});
}
getResourcesData = async () => {
const { mutator } = this.props;
const fetchResourcesPromises = Object.values(mutator)
.reduce((res, resourceMutator) => {
return res.concat(this.getResourceData(resourceMutator));
}, []);
try {
await Promise.all(fetchResourcesPromises);
this.mapResourcesToState();
} catch (e) {
// TODO: should be described in UIDATIMP-53
}
};
async getResourceData({ GET, reset }) {
// accumulate: true in manifest saves the results of all requests
// because of that it is required to clear old data by invoking reset method before each request
reset();
await GET();
}
mapResourcesToState() {
const { resources } = this.props;
const contextData = {};
Object.entries(resources)
.forEach(([resourceName, resourceValue]) => {
contextData[resourceName] = {
hasLoaded: true,
itemsObject: get(resourceValue, ['records', 0], {}),
};
});
this.setState({
contextData,
});
}
}
export default DataFetcher;