mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-12-11 10:13:55 -06:00
Add advanced options to servers
This commit is contained in:
parent
4947e0490a
commit
e997d11c2c
14
package-lock.json
generated
14
package-lock.json
generated
@ -16,7 +16,7 @@
|
||||
"@json2csv/plainjs": "^7.0.6",
|
||||
"@reduxjs/toolkit": "^2.7.0",
|
||||
"@shlinkio/data-manipulation": "^1.0.3",
|
||||
"@shlinkio/shlink-frontend-kit": "^0.8.10",
|
||||
"@shlinkio/shlink-frontend-kit": "^0.8.12",
|
||||
"@shlinkio/shlink-js-sdk": "^2.1.0",
|
||||
"@shlinkio/shlink-web-component": "^0.13.3",
|
||||
"bootstrap": "5.2.3",
|
||||
@ -3438,9 +3438,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@shlinkio/shlink-frontend-kit": {
|
||||
"version": "0.8.10",
|
||||
"resolved": "https://registry.npmjs.org/@shlinkio/shlink-frontend-kit/-/shlink-frontend-kit-0.8.10.tgz",
|
||||
"integrity": "sha512-cB5qyZBCWEwLzEf3XK6ih/32x8i4ER4Tn6WNqIROhcr6Myjot0gvAfNStoXbEeYjJSw2+5wRFSccbAh3w5RxJA==",
|
||||
"version": "0.8.12",
|
||||
"resolved": "https://registry.npmjs.org/@shlinkio/shlink-frontend-kit/-/shlink-frontend-kit-0.8.12.tgz",
|
||||
"integrity": "sha512-J3t0HnvOaZDLSZ1zjbAn9l025GNTy7XvcKEV5+t8iYirf6THyGCK7JDoY1CfgRWfjiWBCFA+WmzrK92a2PqcAA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1"
|
||||
@ -13699,9 +13699,9 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@shlinkio/shlink-frontend-kit": {
|
||||
"version": "0.8.10",
|
||||
"resolved": "https://registry.npmjs.org/@shlinkio/shlink-frontend-kit/-/shlink-frontend-kit-0.8.10.tgz",
|
||||
"integrity": "sha512-cB5qyZBCWEwLzEf3XK6ih/32x8i4ER4Tn6WNqIROhcr6Myjot0gvAfNStoXbEeYjJSw2+5wRFSccbAh3w5RxJA==",
|
||||
"version": "0.8.12",
|
||||
"resolved": "https://registry.npmjs.org/@shlinkio/shlink-frontend-kit/-/shlink-frontend-kit-0.8.12.tgz",
|
||||
"integrity": "sha512-J3t0HnvOaZDLSZ1zjbAn9l025GNTy7XvcKEV5+t8iYirf6THyGCK7JDoY1CfgRWfjiWBCFA+WmzrK92a2PqcAA==",
|
||||
"requires": {
|
||||
"clsx": "^2.1.1"
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
"@json2csv/plainjs": "^7.0.6",
|
||||
"@reduxjs/toolkit": "^2.7.0",
|
||||
"@shlinkio/data-manipulation": "^1.0.3",
|
||||
"@shlinkio/shlink-frontend-kit": "^0.8.10",
|
||||
"@shlinkio/shlink-frontend-kit": "^0.8.12",
|
||||
"@shlinkio/shlink-js-sdk": "^2.1.0",
|
||||
"@shlinkio/shlink-web-component": "^0.13.3",
|
||||
"bootstrap": "5.2.3",
|
||||
|
||||
@ -4,7 +4,7 @@ import type { GetState } from '../../container/types';
|
||||
import type { ServerWithId } from '../../servers/data';
|
||||
import { hasServerData } from '../../servers/data';
|
||||
|
||||
const apiClients: Record<string, ShlinkApiClient> = {};
|
||||
const apiClients: Map<string, ShlinkApiClient> = new Map();
|
||||
|
||||
const isGetState = (getStateOrSelectedServer: GetState | ServerWithId): getStateOrSelectedServer is GetState =>
|
||||
typeof getStateOrSelectedServer === 'function';
|
||||
@ -18,19 +18,22 @@ const getSelectedServerFromState = (getState: GetState): ServerWithId => {
|
||||
};
|
||||
|
||||
export const buildShlinkApiClient = (httpClient: HttpClient) => (getStateOrSelectedServer: GetState | ServerWithId) => {
|
||||
const { url: baseUrl, apiKey } = isGetState(getStateOrSelectedServer)
|
||||
const { url: baseUrl, apiKey, forwardCredentials } = isGetState(getStateOrSelectedServer)
|
||||
? getSelectedServerFromState(getStateOrSelectedServer)
|
||||
: getStateOrSelectedServer;
|
||||
const serverKey = `${apiKey}_${baseUrl}`;
|
||||
const serverKey = `${apiKey}_${baseUrl}_${forwardCredentials ? 'forward' : 'no-forward'}`;
|
||||
const existingApiClient = apiClients.get(serverKey);
|
||||
|
||||
const apiClient = apiClients[serverKey] ?? new ShlinkApiClient(
|
||||
if (existingApiClient) {
|
||||
return existingApiClient;
|
||||
}
|
||||
|
||||
const apiClient = new ShlinkApiClient(
|
||||
httpClient,
|
||||
{ apiKey, baseUrl },
|
||||
// FIXME Disabling this as it's breaking existing Shlink servers as configured out of the box
|
||||
// { requestCredentials: 'include' },
|
||||
{ requestCredentials: forwardCredentials ? 'include' : undefined },
|
||||
);
|
||||
apiClients[serverKey] = apiClient;
|
||||
|
||||
apiClients.set(serverKey, apiClient);
|
||||
return apiClient;
|
||||
};
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ export interface ServerData {
|
||||
name: string;
|
||||
url: string;
|
||||
apiKey: string;
|
||||
forwardCredentials?: boolean;
|
||||
}
|
||||
|
||||
export interface ServerWithId extends ServerData {
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
import { useToggle } from '@shlinkio/shlink-frontend-kit';
|
||||
import {
|
||||
Checkbox,
|
||||
Details,
|
||||
Label,
|
||||
LabelledInput,
|
||||
LabelledRevealablePasswordInput,
|
||||
SimpleCard,
|
||||
} from '@shlinkio/shlink-frontend-kit/tailwind';
|
||||
import type { FC, PropsWithChildren, ReactNode } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { handleEventPreventingDefault } from '../../utils/utils';
|
||||
import { usePreventDefault } from '../../utils/utils';
|
||||
import type { ServerData } from '../data';
|
||||
|
||||
type ServerFormProps = PropsWithChildren<{
|
||||
@ -18,7 +22,11 @@ export const ServerForm: FC<ServerFormProps> = ({ onSubmit, initialValues, child
|
||||
const [name, setName] = useState(initialValues?.name ?? '');
|
||||
const [url, setUrl] = useState(initialValues?.url ?? '');
|
||||
const [apiKey, setApiKey] = useState(initialValues?.apiKey ?? '');
|
||||
const handleSubmit = handleEventPreventingDefault(() => onSubmit({ name, url, apiKey }));
|
||||
const { flag: forwardCredentials, toggle: toggleForwardCredentials } = useToggle(
|
||||
initialValues?.forwardCredentials ?? false,
|
||||
true,
|
||||
);
|
||||
const handleSubmit = usePreventDefault(() => onSubmit({ name, url, apiKey, forwardCredentials }));
|
||||
|
||||
return (
|
||||
<form name="serverForm" onSubmit={handleSubmit}>
|
||||
@ -31,6 +39,19 @@ export const ServerForm: FC<ServerFormProps> = ({ onSubmit, initialValues, child
|
||||
onChange={(e) => setApiKey(e.target.value)}
|
||||
required
|
||||
/>
|
||||
<Details summary="Advanced options">
|
||||
<div className="tw:flex tw:flex-col tw:gap-1">
|
||||
<Label className="tw:flex tw:items-center tw:gap-x-1.5 tw:cursor-pointer">
|
||||
<Checkbox onChange={toggleForwardCredentials} checked={forwardCredentials} />
|
||||
Forward credentials (like cookies) to this server on every request.
|
||||
</Label>
|
||||
<small className="tw:pl-5.5 tw:text-gray-600 tw:dark:text-gray-400">
|
||||
<b>Important!</b> If you are not sure what this means, leave it unchecked. Enabling this option will
|
||||
make all requests fail for Shlink older than v4.5.0, as it requires the server to set a more strict
|
||||
value for <code className="tw:whitespace-nowrap">Access-Control-Allow-Origin</code> than <code>*</code>.
|
||||
</small>
|
||||
</div>
|
||||
</Details>
|
||||
</SimpleCard>
|
||||
|
||||
<div className="tw:flex tw:items-center tw:justify-end tw:gap-x-2">{children}</div>
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
import type { SyntheticEvent } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const handleEventPreventingDefault = <T>(handler: () => T) => (e: SyntheticEvent) => {
|
||||
e.preventDefault();
|
||||
handler();
|
||||
};
|
||||
/**
|
||||
* Wraps an event handler so that it calls e.preventDefault() before invoking the event handler
|
||||
*/
|
||||
export const usePreventDefault = <Event extends SyntheticEvent = SyntheticEvent>(handler: (e: Event) => void) =>
|
||||
useCallback((e: Event) => {
|
||||
e.preventDefault();
|
||||
handler(e);
|
||||
}, [handler]);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user