Expose container via provider

This commit is contained in:
Alejandro Celaya
2025-11-15 10:20:53 +01:00
parent 6094994cfa
commit f301513f5b
15 changed files with 92 additions and 53 deletions

View File

@@ -1,19 +1,16 @@
import { Button, useParsedQuery } from '@shlinkio/shlink-frontend-kit';
import type { FC } from 'react';
import { NoMenuLayout } from '../common/NoMenuLayout';
import type { FCWithDeps } from '../container/utils';
import { useDependencies } from '../container/utils';
import { useGoBack } from '../utils/helpers/hooks';
import type { ServerData } from './data';
import { isServerWithId } from './data';
import { ServerForm } from './helpers/ServerForm';
import type { WithSelectedServerPropsDeps } from './helpers/withSelectedServer';
import { withSelectedServer } from './helpers/withSelectedServer';
import { useSelectedServer } from './reducers/selectedServer';
import { useServers } from './reducers/servers';
export const EditServer: FCWithDeps<any, WithSelectedServerPropsDeps> = withSelectedServer(() => {
export const EditServer: FC = withSelectedServer(() => {
const { editServer } = useServers();
const { buildShlinkApiClient } = useDependencies(EditServer);
const { selectServer, selectedServer } = useSelectedServer();
const goBack = useGoBack();
const { reconnect } = useParsedQuery<{ reconnect?: 'true' }>();
@@ -25,7 +22,7 @@ export const EditServer: FCWithDeps<any, WithSelectedServerPropsDeps> = withSele
const handleSubmit = (serverData: ServerData) => {
editServer(selectedServer.id, serverData);
if (reconnect === 'true') {
selectServer({ serverId: selectedServer.id, buildShlinkApiClient });
selectServer(selectedServer.id);
}
goBack();
};

View File

@@ -1,31 +1,22 @@
import { Message } from '@shlinkio/shlink-frontend-kit';
import type { FC } from 'react';
import { useEffect } from 'react';
import { useParams } from 'react-router';
import type { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder';
import { NoMenuLayout } from '../../common/NoMenuLayout';
import type { FCWithDeps } from '../../container/utils';
import { useDependencies } from '../../container/utils';
import { isNotFoundServer } from '../data';
import { useSelectedServer } from '../reducers/selectedServer';
import { ServerError } from './ServerError';
export type WithSelectedServerPropsDeps = {
buildShlinkApiClient: ShlinkApiClientBuilder;
};
export function withSelectedServer<T extends object>(
WrappedComponent: FCWithDeps<T, WithSelectedServerPropsDeps>,
) {
const ComponentWrapper: FCWithDeps<T, WithSelectedServerPropsDeps> = (props) => {
const { buildShlinkApiClient } = useDependencies(ComponentWrapper);
export function withSelectedServer<T extends object>(WrappedComponent: FC<T>) {
const ComponentWrapper: FC<T> = (props) => {
const params = useParams<{ serverId: string }>();
const { selectServer, selectedServer } = useSelectedServer();
useEffect(() => {
if (params.serverId) {
selectServer({ serverId: params.serverId, buildShlinkApiClient });
selectServer(params.serverId);
}
}, [buildShlinkApiClient, params.serverId, selectServer]);
}, [params.serverId, selectServer]);
if (!selectedServer) {
return (

View File

@@ -1,6 +1,7 @@
import type { HttpClient } from '@shlinkio/shlink-js-sdk';
import { useCallback, useEffect, useRef } from 'react';
import pack from '../../../package.json';
import { useDependencies } from '../../container/context';
import { useAppDispatch } from '../../store';
import { createAsyncThunk } from '../../store/helpers';
import { hasServerData } from '../data';
@@ -24,12 +25,13 @@ export const fetchServers = createAsyncThunk(
export const useRemoteServers = () => {
const dispatch = useAppDispatch();
const dispatchFetchServer = useCallback((httpClient: HttpClient) => dispatch(fetchServers(httpClient)), [dispatch]);
const [httpClient] = useDependencies<[HttpClient]>('HttpClient');
const dispatchFetchServer = useCallback(() => dispatch(fetchServers(httpClient)), [dispatch, httpClient]);
return { fetchServers: dispatchFetchServer };
};
export const useLoadRemoteServers = (httpClient: HttpClient) => {
export const useLoadRemoteServers = () => {
const { fetchServers } = useRemoteServers();
const { servers } = useServers();
const initialServers = useRef(servers);
@@ -38,7 +40,7 @@ export const useLoadRemoteServers = (httpClient: HttpClient) => {
// Try to fetch the remote servers if the list is empty during first render.
// We use a ref because we don't care if the servers list becomes empty later.
if (Object.keys(initialServers.current).length === 0) {
fetchServers(httpClient);
fetchServers();
}
}, [fetchServers, httpClient]);
}, [fetchServers]);
};

View File

@@ -3,6 +3,7 @@ import { memoizeWith } from '@shlinkio/data-manipulation';
import type { ShlinkHealth } from '@shlinkio/shlink-web-component/api-contract';
import { useCallback } from 'react';
import type { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder';
import { useDependencies } from '../../container/context';
import { useAppDispatch, useAppSelector } from '../../store';
import { createAsyncThunk } from '../../store/helpers';
import { versionToPrintable, versionToSemVer as toSemVer } from '../../utils/helpers/version';
@@ -75,10 +76,11 @@ export const { reducer: selectedServerReducer } = createSlice({
export const useSelectedServer = () => {
const dispatch = useAppDispatch();
const [buildShlinkApiClient] = useDependencies<[ShlinkApiClientBuilder]>('buildShlinkApiClient');
const dispatchResetSelectedServer = useCallback(() => dispatch(resetSelectedServer()), [dispatch]);
const dispatchSelectServer = useCallback(
(options: SelectServerOptions) => dispatch(selectServer(options)),
[dispatch],
(serverId: string) => dispatch(selectServer({ serverId, buildShlinkApiClient })),
[buildShlinkApiClient, dispatch],
);
const selectedServer = useAppSelector(({ selectedServer }) => selectedServer);