/* eslint-disable react/prop-types */ import React, { useContext, useEffect, useRef, useState, useCallback } from 'react'; import toaster from '../../../components/toast'; import Context from '../context'; import Store from '../store'; import { EVENT_BUS_TYPE, PER_LOAD_NUMBER } from '../constants'; import { Utils } from '../../../utils/utils'; const MetadataContext = React.createContext(null); export const MetadataProvider = ({ children, repoID, viewID, ...params }) => { const [isLoading, setLoading] = useState(true); const [metadata, setMetadata] = useState({ rows: [], columns: [] }); const storeRef = useRef(null); const tableChanged = useCallback(() => { setMetadata(storeRef.current.data); }, []); const handleTableError = useCallback((error) => { const errorMsg = Utils.getErrorMsg(error); toaster.danger(errorMsg); }, []); const updateMetadata = useCallback((data) => { setMetadata(data); }, []); const reloadMetadata = useCallback(() => { setLoading(true); storeRef.current.reload(PER_LOAD_NUMBER).then(() => { setMetadata(storeRef.current.data); setLoading(false); }).catch(error => { const errorMsg = Utils.getErrorMsg(error); toaster.danger(errorMsg); }); }, []); // init useEffect(() => { setLoading(true); // init context const context = new Context(); window.sfMetadataContext = context; window.sfMetadataContext.init({ ...params, repoID, viewID }); storeRef.current = new Store({ context: window.sfMetadataContext, repoId: repoID, viewId: viewID }); window.sfMetadataStore = storeRef.current; storeRef.current.initStartIndex(); storeRef.current.load(PER_LOAD_NUMBER).then(() => { setMetadata(storeRef.current.data); setLoading(false); }).catch(error => { const errorMsg = Utils.getErrorMsg(error); toaster.danger(errorMsg); }); const eventBus = window.sfMetadataContext.eventBus; const unsubscribeServerTableChanged = eventBus.subscribe(EVENT_BUS_TYPE.SERVER_TABLE_CHANGED, tableChanged); const unsubscribeTableChanged = eventBus.subscribe(EVENT_BUS_TYPE.LOCAL_TABLE_CHANGED, tableChanged); const unsubscribeHandleTableError = eventBus.subscribe(EVENT_BUS_TYPE.TABLE_ERROR, handleTableError); const unsubscribeUpdateRows = eventBus.subscribe(EVENT_BUS_TYPE.UPDATE_TABLE_ROWS, updateMetadata); const unsubscribeReloadData = eventBus.subscribe(EVENT_BUS_TYPE.RELOAD_DATA, reloadMetadata); return () => { window.sfMetadataContext.destroy(); window.sfMetadataStore.destroy(); unsubscribeServerTableChanged(); unsubscribeTableChanged(); unsubscribeHandleTableError(); unsubscribeUpdateRows(); unsubscribeReloadData(); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [repoID, viewID]); return ( {children} ); }; export const useMetadata = () => { const context = useContext(MetadataContext); if (!context) { throw new Error('\'MetadataContext\' is null'); } const { isLoading, metadata, store } = context; return { isLoading, metadata, store }; };