diff --git a/shlink-web-component/Main.tsx b/shlink-web-component/Main.tsx index a8a0fc1f..57c5d822 100644 --- a/shlink-web-component/Main.tsx +++ b/shlink-web-component/Main.tsx @@ -10,10 +10,6 @@ import { useSwipeable, useToggle } from '../src/utils/helpers/hooks'; import { useFeature } from './utils/features'; import { useRoutesPrefix } from './utils/routesPrefix'; -type MainProps = { - loadMercureInfo: () => void; -}; - export const Main = ( TagsList: FC, ShortUrlsList: FC, @@ -26,22 +22,17 @@ export const Main = ( Overview: FC, EditShortUrl: FC, ManageDomains: FC, -): FC => ({ loadMercureInfo }) => { +): FC => () => { const location = useLocation(); const routesPrefix = useRoutesPrefix(); const [sidebarVisible, toggleSidebar, showSidebar, hideSidebar] = useToggle(); useEffect(() => hideSidebar(), [location]); - // FIXME Re-load mercure info every time server changes - // useEffect(() => { - // loadMercureInfo(); - // }, []); - const addDomainVisitsRoute = useFeature('domainVisits'); const burgerClasses = classNames('menu-layout__burger-icon', { 'menu-layout__burger-icon--active': sidebarVisible }); const swipeableProps = useSwipeable(showSidebar, hideSidebar); - // TODO Check if this is already wrapped by a router, and wrap otherwise + // FIXME Check if this is already wrapped by a router, and wrap otherwise return ( <> diff --git a/shlink-web-component/ShlinkWebComponent.tsx b/shlink-web-component/ShlinkWebComponent.tsx index e166418f..3cf5d3a0 100644 --- a/shlink-web-component/ShlinkWebComponent.tsx +++ b/shlink-web-component/ShlinkWebComponent.tsx @@ -24,15 +24,13 @@ let apiClientRef: ShlinkApiClient; export const createShlinkWebComponent = ( bottle: Bottle, -): FC => ({ routesPrefix = '', serverVersion, settings, apiClient }) => { +): FC => ({ serverVersion, apiClient, settings, routesPrefix = '' }) => { const features = useFeatures(serverVersion); const mainContent = useRef(); const [theStore, setStore] = useState(); - // Set client on every re-render - apiClientRef = apiClient; - useEffect(() => { + apiClientRef = apiClient; bottle.value('apiClientFactory', () => apiClientRef); // It's important to not try to resolve services before the API client has been registered, as many other services @@ -43,8 +41,8 @@ export const createShlinkWebComponent = ( setStore(store); // Load mercure info - store.dispatch(loadMercureInfo()); - }, []); + store.dispatch(loadMercureInfo(settings)); + }, [apiClient]); return !theStore ? <> : ( diff --git a/shlink-web-component/container/provideServices.ts b/shlink-web-component/container/provideServices.ts index 4b3489ed..11bbd36f 100644 --- a/shlink-web-component/container/provideServices.ts +++ b/shlink-web-component/container/provideServices.ts @@ -1,9 +1,8 @@ import type Bottle from 'bottlejs'; import { Main } from '../Main'; -import type { ConnectDecorator } from './index'; import { setUpStore } from './store'; -export const provideServices = (bottle: Bottle, connect: ConnectDecorator) => { +export const provideServices = (bottle: Bottle) => { bottle.serviceFactory( 'Main', Main, @@ -19,7 +18,6 @@ export const provideServices = (bottle: Bottle, connect: ConnectDecorator) => { 'EditShortUrl', 'ManageDomains', ); - bottle.decorator('Main', connect(null, ['loadMercureInfo'])); bottle.factory('store', setUpStore); }; diff --git a/shlink-web-component/mercure/reducers/mercureInfo.ts b/shlink-web-component/mercure/reducers/mercureInfo.ts index 16c2e311..ac94f780 100644 --- a/shlink-web-component/mercure/reducers/mercureInfo.ts +++ b/shlink-web-component/mercure/reducers/mercureInfo.ts @@ -1,6 +1,7 @@ import { createSlice } from '@reduxjs/toolkit'; import type { ShlinkApiClient, ShlinkMercureInfo } from '../../api-contract'; import { createAsyncThunk } from '../../utils/redux'; +import type { Settings } from '../../utils/settings'; const REDUCER_PREFIX = 'shlink/mercure'; @@ -18,15 +19,13 @@ const initialState: MercureInfo = { export const mercureInfoReducerCreator = (apiClientFactory: () => ShlinkApiClient) => { const loadMercureInfo = createAsyncThunk( `${REDUCER_PREFIX}/loadMercureInfo`, - (): Promise => - // FIXME Get settings here somehow, as they are only available via hook - // const { settings } = getState(); - // if (!settings.realTimeUpdates.enabled) { - // throw new Error('Real time updates not enabled'); - // } + ({ realTimeUpdates }: Settings): Promise => { + if (realTimeUpdates && !realTimeUpdates.enabled) { + throw new Error('Real time updates not enabled'); + } - apiClientFactory().mercureInfo() - , + return apiClientFactory().mercureInfo(); + }, ); const { reducer } = createSlice({ diff --git a/src/common/MenuLayout.tsx b/src/common/MenuLayout.tsx index 12c87569..ec2b75b8 100644 --- a/src/common/MenuLayout.tsx +++ b/src/common/MenuLayout.tsx @@ -1,7 +1,7 @@ import type { FC } from 'react'; import { useEffect } from 'react'; +import type { Settings } from '../../shlink-web-component'; import { ShlinkWebComponent } from '../../shlink-web-component'; -import type { Settings } from '../../shlink-web-component/utils/settings'; import type { ShlinkApiClientBuilder } from '../api/services/ShlinkApiClientBuilder'; import { isReachableServer } from '../servers/data'; import { withSelectedServer } from '../servers/helpers/withSelectedServer'; diff --git a/src/servers/reducers/selectedServer.ts b/src/servers/reducers/selectedServer.ts index 89a66bb2..912fd6a7 100644 --- a/src/servers/reducers/selectedServer.ts +++ b/src/servers/reducers/selectedServer.ts @@ -1,12 +1,10 @@ -import type { PayloadAction } from '@reduxjs/toolkit'; -import { createAction, createListenerMiddleware, createSlice } from '@reduxjs/toolkit'; +import { createAction, createSlice } from '@reduxjs/toolkit'; import { memoizeWith, pipe } from 'ramda'; +import type { ShlinkHealth } from '../../../shlink-web-component/api-contract'; import type { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder'; -import type { ShlinkHealth } from '../../api/types'; import { createAsyncThunk } from '../../utils/helpers/redux'; import { versionToPrintable, versionToSemVer as toSemVer } from '../../utils/helpers/version'; import type { SelectedServer, ServerWithId } from '../data'; -import { isReachableServer } from '../data'; const REDUCER_PREFIX = 'shlink/selectedServer'; diff --git a/src/settings/RealTimeUpdatesSettings.tsx b/src/settings/RealTimeUpdatesSettings.tsx index 99be265f..ad7469ca 100644 --- a/src/settings/RealTimeUpdatesSettings.tsx +++ b/src/settings/RealTimeUpdatesSettings.tsx @@ -1,23 +1,24 @@ import classNames from 'classnames'; import { FormGroup, Input } from 'reactstrap'; +import type { Settings } from '../../shlink-web-component'; import { FormText } from '../utils/forms/FormText'; import { LabeledFormGroup } from '../utils/forms/LabeledFormGroup'; import { useDomId } from '../utils/helpers/hooks'; import { SimpleCard } from '../utils/SimpleCard'; import { ToggleSwitch } from '../utils/ToggleSwitch'; -import type { Settings } from './reducers/settings'; -interface RealTimeUpdatesProps { +type RealTimeUpdatesProps = { settings: Settings; toggleRealTimeUpdates: (enabled: boolean) => void; setRealTimeUpdatesInterval: (interval: number) => void; -} +}; const intervalValue = (interval?: number) => (!interval ? '' : `${interval}`); export const RealTimeUpdatesSettings = ( - { settings: { realTimeUpdates }, toggleRealTimeUpdates, setRealTimeUpdatesInterval }: RealTimeUpdatesProps, + { settings, toggleRealTimeUpdates, setRealTimeUpdatesInterval }: RealTimeUpdatesProps, ) => { + const { realTimeUpdates = { enabled: true } } = settings; const inputId = useDomId(); return (