Always show update and health check buttons for proxy provider
ref #649
This commit is contained in:
parent
e62b958e30
commit
69423bdfff
8 changed files with 102 additions and 67 deletions
|
@ -4,6 +4,7 @@ import Loading from 'src/components/Loading';
|
|||
|
||||
import Button from './Button';
|
||||
import Input from './Input';
|
||||
import { ZapAnimated } from './shared/ZapAnimated';
|
||||
import SwitchThemed from './SwitchThemed';
|
||||
import ToggleSwitch from './ToggleSwitch';
|
||||
|
||||
|
@ -42,6 +43,9 @@ class StyleGuide extends PureComponent {
|
|||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Pane>
|
||||
<ZapAnimated />
|
||||
</Pane>
|
||||
<Pane>
|
||||
<SwitchExample />
|
||||
</Pane>
|
||||
|
|
|
@ -4,17 +4,10 @@
|
|||
|
||||
.groupHead {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.latencyButton {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.zapWrapper {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.action {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
|
|
@ -1,26 +1,20 @@
|
|||
import Tooltip from '@reach/tooltip';
|
||||
import * as React from 'react';
|
||||
import { Zap } from 'react-feather';
|
||||
|
||||
import { useState2 } from '$src/hooks/basic';
|
||||
import { State } from '$src/store/types';
|
||||
|
||||
import { getCollapsibleIsOpen, getHideUnavailableProxies, getProxySortBy } from '../../store/app';
|
||||
import { getProxies, switchProxy } from '../../store/proxies';
|
||||
import Button from '../Button';
|
||||
import CollapsibleSectionHeader from '../CollapsibleSectionHeader';
|
||||
import { ZapAnimated } from '../shared/ZapAnimated';
|
||||
import { connect, useStoreActions } from '../StateProvider';
|
||||
import { useFilteredAndSorted } from './hooks';
|
||||
import s0 from './ProxyGroup.module.scss';
|
||||
import { ProxyList, ProxyListSummaryView } from './ProxyList';
|
||||
|
||||
const { createElement, useCallback, useMemo, useState } = React;
|
||||
|
||||
function ZapWrapper() {
|
||||
return (
|
||||
<div className={s0.zapWrapper}>
|
||||
<Zap size={16} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const { createElement, useCallback, useMemo } = React;
|
||||
|
||||
function ProxyGroupImpl({
|
||||
name,
|
||||
|
@ -56,14 +50,15 @@ function ProxyGroupImpl({
|
|||
[apiConfig, dispatch, name, isSelectable]
|
||||
);
|
||||
|
||||
const [isTestingLatency, setIsTestingLatency] = useState(false);
|
||||
const testingLatency = useState2(false);
|
||||
const testLatency = useCallback(async () => {
|
||||
setIsTestingLatency(true);
|
||||
if (testingLatency.value) return;
|
||||
testingLatency.set(true);
|
||||
try {
|
||||
await requestDelayForProxies(apiConfig, all);
|
||||
} catch (err) {}
|
||||
setIsTestingLatency(false);
|
||||
}, [all, apiConfig, requestDelayForProxies]);
|
||||
testingLatency.set(false);
|
||||
}, [all, apiConfig, requestDelayForProxies, testingLatency]);
|
||||
|
||||
return (
|
||||
<div className={s0.group}>
|
||||
|
@ -75,15 +70,13 @@ function ProxyGroupImpl({
|
|||
qty={all.length}
|
||||
isOpen={isOpen}
|
||||
/>
|
||||
<Button
|
||||
className={s0.latencyButton}
|
||||
title="Test latency"
|
||||
kind="minimal"
|
||||
onClick={testLatency}
|
||||
isLoading={isTestingLatency}
|
||||
>
|
||||
<ZapWrapper />
|
||||
<div className={s0.action}>
|
||||
<Tooltip label={'Test latency'}>
|
||||
<Button kind="circular" onClick={testLatency}>
|
||||
<ZapAnimated animate={testingLatency.value} size={16} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
{createElement(isOpen ? ProxyList : ProxyListSummaryView, {
|
||||
all,
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
}
|
||||
|
||||
.listSummaryView {
|
||||
margin: 8px 0;
|
||||
margin: 14px 0;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, 13px);
|
||||
grid-gap: 10px;
|
||||
place-items: center;
|
||||
max-width: 900px;
|
||||
}
|
||||
|
|
|
@ -5,21 +5,25 @@
|
|||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
.main {
|
||||
padding: 10px 15px;
|
||||
@media (--breakpoint-not-small) {
|
||||
padding: 10px 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.actionFooter {
|
||||
.head {
|
||||
display: flex;
|
||||
button {
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.action {
|
||||
margin: 0 5px;
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
gap: 10px;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.refresh {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Tooltip from '@reach/tooltip';
|
||||
import { formatDistance } from 'date-fns';
|
||||
import * as React from 'react';
|
||||
import { RotateCw, Zap } from 'react-feather';
|
||||
import { RotateCw } from 'react-feather';
|
||||
import Button from 'src/components/Button';
|
||||
import Collapsible from 'src/components/Collapsible';
|
||||
import CollapsibleSectionHeader from 'src/components/CollapsibleSectionHeader';
|
||||
import { useUpdateProviderItem } from 'src/components/proxies/proxies.hooks';
|
||||
import { connect, useStoreActions } from 'src/components/StateProvider';
|
||||
|
@ -18,6 +18,7 @@ import { DelayMapping, State } from 'src/store/types';
|
|||
|
||||
import { useState2 } from '$src/hooks/basic';
|
||||
|
||||
import { ZapAnimated } from '../shared/ZapAnimated';
|
||||
import { useFilteredAndSorted } from './hooks';
|
||||
import { ProxyList, ProxyListSummaryView } from './ProxyList';
|
||||
import s from './ProxyProvider.module.scss';
|
||||
|
@ -56,6 +57,7 @@ function ProxyProviderImpl({
|
|||
const updateProvider = useUpdateProviderItem({ dispatch, apiConfig, name });
|
||||
|
||||
const healthcheckProvider = useCallback(() => {
|
||||
if (checkingHealth.value) return;
|
||||
checkingHealth.set(true);
|
||||
const stop = () => checkingHealth.set(false);
|
||||
dispatch(healthcheckProviderByName(apiConfig, name)).then(stop, stop);
|
||||
|
@ -71,7 +73,8 @@ function ProxyProviderImpl({
|
|||
|
||||
const timeAgo = formatDistance(new Date(updatedAt), new Date());
|
||||
return (
|
||||
<div className={s.body}>
|
||||
<div className={s.main}>
|
||||
<div className={s.head}>
|
||||
<CollapsibleSectionHeader
|
||||
name={name}
|
||||
toggle={toggle}
|
||||
|
@ -79,24 +82,24 @@ function ProxyProviderImpl({
|
|||
isOpen={isOpen}
|
||||
qty={proxies.length}
|
||||
/>
|
||||
|
||||
<div className={s.action}>
|
||||
<Tooltip label={'Update'}>
|
||||
<Button kind="circular" onClick={updateProvider}>
|
||||
<Refresh />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip label={'Health Check'}>
|
||||
<Button kind="circular" onClick={healthcheckProvider}>
|
||||
<ZapAnimated animate={checkingHealth.value} size={16} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div className={s.updatedAt}>
|
||||
<small>Updated {timeAgo} ago</small>
|
||||
</div>
|
||||
<Collapsible isOpen={isOpen}>
|
||||
<ProxyList all={proxies} />
|
||||
<div className={s.actionFooter}>
|
||||
<Button text="Update" start={<Refresh />} onClick={updateProvider} />
|
||||
<Button
|
||||
text="Health Check"
|
||||
start={<Zap size={16} />}
|
||||
onClick={healthcheckProvider}
|
||||
isLoading={checkingHealth.value}
|
||||
/>
|
||||
</div>
|
||||
</Collapsible>
|
||||
<Collapsible isOpen={!isOpen}>
|
||||
<ProxyListSummaryView all={proxies} />
|
||||
</Collapsible>
|
||||
{isOpen ? <ProxyList all={proxies} /> : <ProxyListSummaryView all={proxies} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
12
src/components/shared/ZapAnimated.module.scss
Normal file
12
src/components/shared/ZapAnimated.module.scss
Normal file
|
@ -0,0 +1,12 @@
|
|||
.animate {
|
||||
--saturation: 70%;
|
||||
stroke: hsl(46deg var(--saturation) 45%);
|
||||
animation: zap-pulse 0.7s 0s ease-in-out none normal infinite;
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
@keyframes zap-pulse {
|
||||
0% { stroke: hsl(46deg var(--saturation) 45%); }
|
||||
50% { stroke: hsl(46deg var(--saturation) 95%); }
|
||||
100% { stroke: hsl(46deg var(--saturation) 45%); }
|
||||
}
|
25
src/components/shared/ZapAnimated.tsx
Normal file
25
src/components/shared/ZapAnimated.tsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
import cx from 'clsx';
|
||||
import * as React from 'react';
|
||||
|
||||
import s from './ZapAnimated.module.scss';
|
||||
|
||||
export function ZapAnimated(props: { size?: number; animate?: boolean }) {
|
||||
const size = props.size || 24;
|
||||
const cls = cx({ [s.animate]: props.animate });
|
||||
return (
|
||||
<svg
|
||||
className={cls}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
|
||||
</svg>
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue