diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 207741364..cc3ccdfca 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -1,6 +1,5 @@ -// Libraries import { Suspense } from 'react'; -import { Provider} from 'react-redux'; +import { Provider } from 'react-redux'; import { PersistGate } from 'redux-persist/integration/react'; import { FullPageLoader } from '@contentstack/venus-components'; @@ -14,28 +13,30 @@ import AppLayout from './components/layout/AppLayout'; // Styles import '@contentstack/venus-components/build/main.css'; import './scss/App.scss'; +import { useNetworkCheck } from './components/NetworkProvider'; function App() { + const isOnline = useNetworkCheck(); return ( - - }> - - } persistor={persistor}> - - - - - - - + <> + {isOnline ? ( + + }> + + } persistor={persistor}> + + + + + + + + ) : ( +

You lost the network connection!

+ )} + ); } export default App; - - -function dispatch(arg0: any) { - throw new Error('Function not implemented.'); -} - diff --git a/ui/src/components/DestinationStack/Actions/LoadStacks.tsx b/ui/src/components/DestinationStack/Actions/LoadStacks.tsx index 60c190958..60a76283d 100644 --- a/ui/src/components/DestinationStack/Actions/LoadStacks.tsx +++ b/ui/src/components/DestinationStack/Actions/LoadStacks.tsx @@ -1,7 +1,6 @@ // Libraries import { useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { Params, useParams } from 'react-router'; import { Select, cbModal, TextInput, SkeletonTile } from '@contentstack/venus-components'; // Redux @@ -65,7 +64,7 @@ const LoadStacks = (props: LoadFileFormatProps) => { ]; const [allStack, setAllStack] = useState(newMigrationData?.destination_stack?.stackArray); const [allLocales] = useState([]); - const [isSaving, setIsSaving] = useState(false); + // const [isSaving, setIsSaving] = useState(false); const [isLoading] = useState(false); const [isError, setIsError] = useState(false); const [errorMessage, setErrorMessage] = useState(''); @@ -84,19 +83,12 @@ const LoadStacks = (props: LoadFileFormatProps) => { },[newMigrationData?.destination_stack?.selectedStack]) //Handle new stack details const handleOnSave = async (data: Stack) => { - setIsSaving(true); - - if (isEmptyString(data?.name) || isEmptyString(data?.locale)) { - setIsSaving(false); - } - // Post data to backend const resp = await createStacksInOrg(selectedOrganisation?.value, { ...data, master_locale: data?.locale }); - setIsSaving(false); - + if (resp.status === 201) { if (newMigrationData?.destination_stack?.stackArray?.length > 0) { await fetchData(); @@ -240,7 +232,6 @@ const LoadStacks = (props: LoadFileFormatProps) => { shouldCloseOnOverlayClick: true, onClose: () => { setIsError(false) - return; }, onOpen: () => { return; diff --git a/ui/src/components/DestinationStack/index.tsx b/ui/src/components/DestinationStack/index.tsx index 45d79af24..f048a708a 100644 --- a/ui/src/components/DestinationStack/index.tsx +++ b/ui/src/components/DestinationStack/index.tsx @@ -39,7 +39,7 @@ const DestinationStackComponent = ({ const [isLoading, setIsLoading] = useState(true); // const [isCompleted, setIsCompleted] = useState(false); const [isMigrationLocked, setIsMigrationLocked] = useState(false); - const [stepperKey, setStepperKey] = useState('destination-Vertical-stepper'); + const [stepperKey] = useState('destination-Vertical-stepper'); const [internalActiveStepIndex, setInternalActiveStepIndex] = useState(-1); const autoVerticalStepperComponent = useRef(null); diff --git a/ui/src/components/NetworkProvider/index.tsx b/ui/src/components/NetworkProvider/index.tsx new file mode 100644 index 000000000..46d4532fa --- /dev/null +++ b/ui/src/components/NetworkProvider/index.tsx @@ -0,0 +1,29 @@ +import { useDispatch, useSelector } from 'react-redux'; +import { useEffect, useCallback } from 'react'; +import { setOnline, setOffline, selectNetworkStatus } from '../../store/slice/networkSlice'; +import { RootState } from '../../store'; + +export const useNetworkCheck = () => { + const dispatch = useDispatch(); + const isOnline = useSelector((state: RootState) => selectNetworkStatus(state)); + + const setOnlineToTrue = useCallback(() => { + dispatch(setOnline()); + }, [dispatch]); + + const setOnlineToFalse = useCallback(() => { + dispatch(setOffline()); + }, [dispatch]); + + useEffect(() => { + window.addEventListener('online', setOnlineToTrue); + window.addEventListener('offline', setOnlineToFalse); + + return () => { + window.removeEventListener('online', setOnlineToTrue); + window.removeEventListener('offline', setOnlineToFalse); + }; + }, [setOnlineToTrue, setOnlineToFalse]); + + return isOnline; +}; diff --git a/ui/src/index.css b/ui/src/index.css index 89e57c7cc..3f19ad978 100644 --- a/ui/src/index.css +++ b/ui/src/index.css @@ -9,3 +9,10 @@ body { code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } + +.internetConnection { + display: flex; + align-items: center; + justify-content: center; + height: 80vh; +} \ No newline at end of file diff --git a/ui/src/index.tsx b/ui/src/index.tsx index 64196f726..a44d1edb9 100644 --- a/ui/src/index.tsx +++ b/ui/src/index.tsx @@ -5,11 +5,15 @@ import { BrowserRouter } from 'react-router-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; +import { Provider } from 'react-redux'; +import { store } from './store'; const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); root.render( - + + + ); diff --git a/ui/src/store/index.tsx b/ui/src/store/index.tsx index 8ba9b8184..bcc62715b 100644 --- a/ui/src/store/index.tsx +++ b/ui/src/store/index.tsx @@ -8,7 +8,7 @@ import { combineReducers, configureStore, Tuple} from '@reduxjs/toolkit'; import storage from 'redux-persist/lib/storage'; import { persistReducer, persistStore } from 'redux-persist'; import authMiddleware from './middleware/authMiddleware'; - +import networkReducer from './slice/networkSlice'; const persistConfig = { key: 'root', @@ -19,6 +19,7 @@ const persistConfig = { const rootReducer = combineReducers({ migration: migrationDataSlice, authentication: authSlice, + network: networkReducer, }); const persistedReducer = persistReducer(persistConfig, rootReducer); diff --git a/ui/src/store/slice/networkSlice.tsx b/ui/src/store/slice/networkSlice.tsx new file mode 100644 index 000000000..5793d49b1 --- /dev/null +++ b/ui/src/store/slice/networkSlice.tsx @@ -0,0 +1,29 @@ +import { createSlice } from '@reduxjs/toolkit'; +import { RootState } from '../../store'; + +interface NetworkState { + isOnline: boolean; +} + +const initialState: NetworkState = { + isOnline: navigator.onLine, +}; + +const networkSlice = createSlice({ + name: 'network', + initialState, + reducers: { + setOnline(state) { + state.isOnline = true; + }, + setOffline(state) { + state.isOnline = false; + }, + }, +}); + +export const { setOnline, setOffline } = networkSlice.actions; + +export const selectNetworkStatus = (state: RootState) => state.network.isOnline; + +export default networkSlice.reducer;