Verified Commit 1c76b699 authored by Florent Chehab's avatar Florent Chehab
Browse files

feat(frontend): updated withNetworkWrapper accordingly

parent 81886f4f
import { setDisplayName } from "recompose";
import React from "react";
import PropTypes from "prop-types";
import React, { useEffect } from "react";
import RequestParams from "../utils/api/RequestParams";
import Loading from "../components/common/Loading";
import useSingleApiData from "../hooks/wrappers/useSingleApiData";
export function getApiPropTypes(...keys) {
const shape = {};
keys.forEach(key => {
shape[key] = PropTypes.shape({
setParams: PropTypes.func.isRequired
}).isRequired;
});
return PropTypes.shape(shape);
}
/**
* Simple class to the standardize the way data is requested.
*/
......@@ -55,6 +43,19 @@ export class NetWrapParam {
}
}
/**
* Helper to extract the data from the props based on a NetWrapParam instance
* @param {Object} props
* @param {NetWrapParam} netWrapParam
* @returns {Object} -- sub object from props
*/
function extractProps(props, netWrapParam) {
return Object.fromEntries(
// eslint-disable-next-line react/forbid-foreign-prop-types
Object.entries(props).filter(([key]) => key in netWrapParam.propTypes)
);
}
/**
* HOC Component to inject the data from the backend.
*
......@@ -83,14 +84,28 @@ export default function withNetworkWrapper(
// We need to forward the ref otherwise the styles are not correctly applied.
// eslint-disable-next-line react/display-name
React.forwardRef((props, ref) => {
const allData = parameters.map(el => [
useSingleApiData(el.routeName, el.variant, () =>
typeof el.params === "function" ? el.params(props) : el.params
const allData = parameters.map(netWrapParam => [
useSingleApiData(netWrapParam.routeName, netWrapParam.variant, () =>
typeof netWrapParam.params === "function"
? netWrapParam.params(extractProps(props, netWrapParam))
: netWrapParam.params
),
el.propKey
netWrapParam.propKey
]);
const allHooks = allData.map(el => el[0]);
// eslint-disable-next-line no-plusplus
parameters.forEach((netWrapParam, idx) => {
if (typeof netWrapParam.params === "function") {
// check if we automatically need to actualize
const propsExtract = extractProps(props, netWrapParam);
useEffect(() => {
const associatedHook = allHooks[idx];
associatedHook.setParams(netWrapParam.params(propsExtract));
}, Object.values(propsExtract));
}
});
// Error handling
const hasError = allHooks.some(hook => hook.hasError);
if (hasError) return <div>Error</div>;
......@@ -106,6 +121,20 @@ export default function withNetworkWrapper(
newProps.api[propName] = hook;
});
// Magically re-add proptypes in dev to make we are not missing anything
if (process.env.NODE_ENV !== "production") {
// eslint-disable-next-line react/forbid-foreign-prop-types
const { propTypes = {} } = Component;
// eslint-disable-next-line no-param-reassign
Component.propTypes = {
...Object.assign(
{},
...parameters.map(netWrapParams => netWrapParams.propTypes)
),
...propTypes
};
}
return <Component {...props} {...newProps} ref={ref} />;
})
);
......
......@@ -9,7 +9,7 @@ import useOnBeforeComponentMount from "../useOnBeforeComponentMount";
*
* @param {string} routeName - Route from where to get the data
* @param {"all"|"one"} variant - Is it a "all" or a "one" (GET all or GET one object)
* @param {RequestParams} [initialParams] - RequestParams for the first request.
* @param {RequestParams|function():RequestParams} [initialParams] - RequestParams for the first request.
* @returns {{isLoading: boolean, data: ({}|Function), latestData: *, hasError: boolean, setParams: React.Dispatch<React.SetStateAction<RequestParams>>}}
*/
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment