diff --git a/src/fireedge/src/client/constants/setting.js b/src/fireedge/src/client/constants/setting.js index b607f46408..c67fa775a4 100644 --- a/src/fireedge/src/client/constants/setting.js +++ b/src/fireedge/src/client/constants/setting.js @@ -13,9 +13,7 @@ * See the License for the specific language governing permissions and * * limitations under the License. * * ------------------------------------------------------------------------- */ -/** - * @enum {string} Scheme type - */ +/** @enum {string} Scheme type */ export const SCHEMES = { SYSTEM: 'system', DARK: 'dark', diff --git a/src/fireedge/src/client/constants/states.js b/src/fireedge/src/client/constants/states.js index 30a3e95df4..234d8a4417 100644 --- a/src/fireedge/src/client/constants/states.js +++ b/src/fireedge/src/client/constants/states.js @@ -13,6 +13,9 @@ * See the License for the specific language governing permissions and * * limitations under the License. * * ------------------------------------------------------------------------- */ + +/** @typedef {{color: string, name: string, meaning: string}} StateInfo */ + export const ACTIVE = 'ACTIVE' export const BOOT = 'BOOT' export const BOOT_FAILURE = 'BOOT_FAILURE' diff --git a/src/fireedge/src/client/constants/vm.js b/src/fireedge/src/client/constants/vm.js index 87afef0d35..cfc876859b 100644 --- a/src/fireedge/src/client/constants/vm.js +++ b/src/fireedge/src/client/constants/vm.js @@ -16,6 +16,7 @@ import * as STATES from 'client/constants/states' import COLOR from 'client/constants/color' +/** @type {STATES.StateInfo[]} Virtual machine states */ export const VM_STATES = [ { // 0 name: STATES.INIT, diff --git a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Tiers/Flow/index.js b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Tiers/Flow/index.js index e9f5dfeae7..7695b0c778 100644 --- a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Tiers/Flow/index.js +++ b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Tiers/Flow/index.js @@ -56,7 +56,7 @@ const useStyles = makeStyles(() => ({ * @param {Array} props.dataFields - List of keys * @param {Function} props.handleCreate - Create a new Node * @param {Function} props.handleEdit - Edit a current Node - * @param {boolean} props.handleSetData - Set new list of nodes + * @param {Function} props.handleSetData - Set new list of nodes * @returns {React.JSXElementConstructor} ReactFlow component */ const Flow = memo(({ dataFields, handleCreate, handleEdit, handleSetData }) => { diff --git a/src/fireedge/src/client/hooks/useFetch.js b/src/fireedge/src/client/hooks/useFetch.js index eeb17ff0a6..6dd6e4d273 100644 --- a/src/fireedge/src/client/hooks/useFetch.js +++ b/src/fireedge/src/client/hooks/useFetch.js @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * * limitations under the License. * * ------------------------------------------------------------------------- */ -import { useReducer, useCallback, useEffect, useRef } from 'react' +import { useReducer, useCallback, useEffect, useRef, ReducerState, ReducerAction } from 'react' import { fakeDelay } from 'client/utils' +/** @enum {string} Status of request */ const STATUS = { INIT: 'INIT', PENDING: 'PENDING', @@ -23,6 +24,7 @@ const STATUS = { FETCHED: 'FETCHED' } +/** @enum {string} Type of action */ const ACTIONS = { REQUEST: 'REQUEST', SUCCESS: 'SUCCESS', @@ -37,6 +39,11 @@ const INITIAL_STATE = { reloading: false } +/** + * @param {ReducerState} state - Current state of reducer + * @param {ReducerAction} action - Action will be triggered + * @returns {ReducerState} The reducer state modified with payload + */ const fetchReducer = (state, action) => { const { type, payload, reload = false } = action const { data: currentData } = state @@ -62,6 +69,24 @@ const fetchReducer = (state, action) => { }[type] ?? state } +/** + * Hook to manage a request. + * + * @param {Promise} request - Request to fetch + * @param {object} socket - Socket to update the global state after success + * @param {Function} socket.connect - Connect to socket + * @param {Function} socket.disconnect - Disconnect to socket + * @returns {{ + * status: STATUS, + * error: object|string, + * data: object|Array, + * loading: boolean, + * reloading: boolean, + * fetchRequest: Function, + * STATUS: STATUS, + * ACTIONS: ACTIONS + * }} - List of functions to interactive with FireEdge sockets + */ const useFetch = (request, socket) => { const cancelRequest = useRef(false) const [state, dispatch] = useReducer(fetchReducer, INITIAL_STATE) @@ -101,22 +126,33 @@ const useFetch = (request, socket) => { const errorMessage = typeof error === 'string' ? error : error?.message dispatch({ type: ACTIONS.FAILURE, payload: errorMessage }) + + return error } }, [request, cancelRequest.current, dispatch]) - const fetchRequest = useCallback((payload, options = {}) => { - const { reload = false, delay = 0 } = options + const fetchRequest = useCallback( + /** + * @param {Array|string|number|object} [payload] - Payload to request + * @param {object} options - Options to trigger the request + * @param {boolean} options.reload + * - If `true`, the state will be change `reloading` instead of `loading` + * @param {number} options.delay - Delay to trigger the request + * @returns {Promise} - Returns a promise with response or error + */ + (payload, options = {}) => { + const { reload = false, delay = 0 } = options - if (!(Number.isInteger(delay) && delay >= 0)) { - console.error(` + if (!(Number.isInteger(delay) && delay >= 0)) { + console.error(` Delay must be a number >= 0! If you're using it as a function, it must also return a number >= 0.`) - } + } - return fakeDelay(delay).then(() => doFetch(payload, reload)) - }, [request]) + return fakeDelay(delay).then(() => doFetch(payload, reload)) + }, [request]) - return { ...state, fetchRequest, STATUS, ACTIONS, INITIAL_STATE } + return { ...state, fetchRequest, STATUS, ACTIONS } } export default useFetch diff --git a/src/fireedge/src/client/hooks/useFetchAll.js b/src/fireedge/src/client/hooks/useFetchAll.js index 97f8695bc4..248eb13a30 100644 --- a/src/fireedge/src/client/hooks/useFetchAll.js +++ b/src/fireedge/src/client/hooks/useFetchAll.js @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * * limitations under the License. * * ------------------------------------------------------------------------- */ -import { useReducer, useCallback, useEffect, useRef } from 'react' +import { useReducer, useCallback, useEffect, useRef, ReducerState, ReducerAction } from 'react' import { fakeDelay } from 'client/utils' +/** @enum {string} Status of request */ const STATUS = { INIT: 'INIT', PENDING: 'PENDING', @@ -23,6 +24,7 @@ const STATUS = { FETCHED: 'FETCHED' } +/** @enum {string} Type of action */ const ACTIONS = { REQUEST: 'REQUEST', SUCCESS: 'SUCCESS', @@ -37,6 +39,11 @@ const INITIAL_STATE = { reloading: false } +/** + * @param {ReducerState} state - Current state of reducer + * @param {ReducerAction} action - Action will be triggered + * @returns {ReducerState} The reducer state modified with payload + */ const fetchReducer = (state, action) => { const { type, payload, reload = false } = action const { data: currentData } = state @@ -62,6 +69,20 @@ const fetchReducer = (state, action) => { }[type] ?? state } +/** + * Hook to manage a group of requests. + * + * @returns {{ + * status: STATUS, + * error: object|string, + * data: object|Array, + * loading: boolean, + * reloading: boolean, + * fetchRequestAll: Function, + * STATUS: STATUS, + * ACTIONS: ACTIONS + * }} - List of properties to fetch a group of requests + */ const useFetchAll = () => { const cancelRequest = useRef(false) const [state, dispatch] = useReducer(fetchReducer, INITIAL_STATE) @@ -80,28 +101,41 @@ const useFetchAll = () => { if (cancelRequest.current) return dispatch({ type: ACTIONS.SUCCESS, payload: response }) + + return response } catch (error) { if (cancelRequest.current) return const errorMessage = typeof error === 'string' ? error : error?.message dispatch({ type: ACTIONS.FAILURE, payload: errorMessage }) + + return error } } - const fetchRequestAll = useCallback((requests, options = {}) => { - const { reload = false, delay = 0 } = options + const fetchRequestAll = useCallback( + /** + * @param {Function[]} requests - Array of requests to fetch + * @param {object} options - Options to trigger the request + * @param {boolean} options.reload + * - If `true`, the state will be change `reloading` instead of `loading` + * @param {number} options.delay - Delay to trigger the request + * @returns {Promise} - Returns a promise with responses or error + */ + (requests, options = {}) => { + const { reload = false, delay = 0 } = options - if (!(Number.isInteger(delay) && delay >= 0)) { - console.error(` + if (!(Number.isInteger(delay) && delay >= 0)) { + console.error(` Delay must be a number >= 0! If you're using it as a function, it must also return a number >= 0.`) - } + } - fakeDelay(delay).then(() => doFetches(requests, reload)) - }, []) + return fakeDelay(delay).then(() => doFetches(requests, reload)) + }, []) - return { ...state, fetchRequestAll, STATUS, ACTIONS, INITIAL_STATE } + return { ...state, fetchRequestAll, STATUS, ACTIONS } } export default useFetchAll diff --git a/src/fireedge/src/client/hooks/useList.js b/src/fireedge/src/client/hooks/useList.js index 80241e9c33..b87ae26748 100644 --- a/src/fireedge/src/client/hooks/useList.js +++ b/src/fireedge/src/client/hooks/useList.js @@ -17,7 +17,23 @@ import { useState, useEffect } from 'react' import PropTypes from 'prop-types' import { fakeDelay } from 'client/utils' -function useList ({ list, initLength }) { +/** + * Hook to manage an infinite list. + * TODO: Make the hook with a reducer. + * + * @param {object} props - Props + * @param {Array} props.list - List of elements + * @param {number} [props.initLength=50] - Initial length of the list + * @returns {{ + * loading: boolean, + * loadingNextPage: boolean, + * shortList: Array, + * finish: boolean, + * reset: Function, + * setLength: Function + * }} - Properties to manage the infinite list + */ +const useList = ({ list, initLength }) => { const [fullList, setFullList] = useState([]) const [shortList, setShortList] = useState([]) const [finish, setFinish] = useState(false) @@ -63,13 +79,11 @@ function useList ({ list, initLength }) { useList.propTypes = { list: PropTypes.arrayOf(PropTypes.object).isRequired, - fetchList: PropTypes.func.isRequired, initLength: PropTypes.string } useList.defaultProps = { list: [], - fetchList: () => undefined, initLength: 50 } diff --git a/src/fireedge/src/client/hooks/useListForm.js b/src/fireedge/src/client/hooks/useListForm.js index 09c080a952..e64ecda2e1 100644 --- a/src/fireedge/src/client/hooks/useListForm.js +++ b/src/fireedge/src/client/hooks/useListForm.js @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * * limitations under the License. * * ------------------------------------------------------------------------- */ -import { useCallback, useState } from 'react' +import { useCallback, useState, SetStateAction } from 'react' import { set } from 'client/utils' const NEXT_INDEX = index => index + 1 @@ -22,36 +22,98 @@ const EXISTS_INDEX = index => index !== -1 const getIndexById = (list, id) => list.findIndex(({ id: itemId }) => itemId === id) +/** + * Hook to manage a list with selectable elements in a form data. + * + * @param {object} props - Props + * @param {boolean} props.multiple - If `true`, can be more than one select elements + * @param {string} props.key - Key of list in the form + * @param {object[]} props.list - Form data + * @param {SetStateAction} props.setList - State action from the form + * @param {{ id: string|number }} props.defaultValue - Default value of element + * @example