mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-11-25 06:25:44 +03:00
Pull request: 684 move block/unblock button to the tooltip menu
Updates #684 Squashed commit of the following: commit 2c5ac44d3edb55d0d3be169fb0bbfb336920964d Merge: 0fce61dfa733d6c1fc
Author: Ildar Kamalov <ik@adguard.com> Date: Mon Oct 16 10:08:58 2023 +0300 Merge branch 'master' into ADG-7200 commit 0fce61dfad31951c3d5a484a14383c58964b47f0 Author: Ildar Kamalov <ik@adguard.com> Date: Fri Oct 13 16:38:13 2023 +0300 fix dashboard clients table block/unblock button commit ef5d72fd7cac81b70503c8813cf6e96952ec3b65 Merge: f49281b88506d71310
Author: Ildar Kamalov <ik@adguard.com> Date: Fri Oct 13 16:16:21 2023 +0300 Merge branch 'master' into ADG-7200 commit f49281b8818728ab298d769b8164919ea415d6c9 Author: Ildar Kamalov <ik@adguard.com> Date: Thu Oct 12 11:25:05 2023 +0300 fix disabled commit 0031861174108214e9741852f6e00c5873c3b20f Author: Ildar Kamalov <ik@adguard.com> Date: Thu Oct 12 11:20:50 2023 +0300 fix icon color commit 2916937b0d6a0d126bd48e59f41a6fcbc4622ea1 Author: Ildar Kamalov <ik@adguard.com> Date: Thu Oct 12 11:15:55 2023 +0300 changelog commit 34493c974fb9304267e9149360c802d9364dd7de Merge: d3267bbe9d3fabdda4
Author: Ildar Kamalov <ik@adguard.com> Date: Thu Oct 12 11:13:43 2023 +0300 Merge branch 'master' into ADG-7200 commit d3267bbe9477d6db0783534cb4ab4f7afc4d63b0 Merge: 58a6c766f6a3661562
Author: Ildar Kamalov <ik@adguard.com> Date: Wed Oct 11 16:46:39 2023 +0300 Merge branch 'master' into ADG-7200 commit 58a6c766f3b783f0e2fdc36d40889042f3c74f2f Author: Ildar Kamalov <ik@adguard.com> Date: Wed Oct 11 16:46:13 2023 +0300 ADG-7200 move block/unblock button to the tooltip menu
This commit is contained in:
parent
733d6c1fca
commit
413f484810
11 changed files with 124 additions and 102 deletions
|
@ -23,12 +23,17 @@ See also the [v0.107.40 GitHub milestone][ms-v0.107.40].
|
||||||
NOTE: Add new changes BELOW THIS COMMENT.
|
NOTE: Add new changes BELOW THIS COMMENT.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- "Block" and "Unblock" buttons of the query log moved to the tooltip menu ([#684]).
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- The time shown in the statistics is one hour less than the current time ([#6296]).
|
- The time shown in the statistics is one hour less than the current time ([#6296]).
|
||||||
- Issues with QUIC and HTTP/3 upstreams on FreeBSD ([#6301]).
|
- Issues with QUIC and HTTP/3 upstreams on FreeBSD ([#6301]).
|
||||||
- Panic on clearing query log ([#6304]).
|
- Panic on clearing query log ([#6304]).
|
||||||
|
|
||||||
|
[#684]: https://github.com/AdguardTeam/AdGuardHome/issues/684
|
||||||
[#6296]: https://github.com/AdguardTeam/AdGuardHome/issues/6296
|
[#6296]: https://github.com/AdguardTeam/AdGuardHome/issues/6296
|
||||||
[#6301]: https://github.com/AdguardTeam/AdGuardHome/issues/6301
|
[#6301]: https://github.com/AdguardTeam/AdGuardHome/issues/6301
|
||||||
[#6304]: https://github.com/AdguardTeam/AdGuardHome/issues/6304
|
[#6304]: https://github.com/AdguardTeam/AdGuardHome/issues/6304
|
||||||
|
|
|
@ -134,15 +134,6 @@ body {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-action {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logs__row:hover .button-action,
|
|
||||||
.button-action--active {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ReactModal__Body--open {
|
.ReactModal__Body--open {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import ReactTable from 'react-table';
|
import ReactTable from 'react-table';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Trans, useTranslation } from 'react-i18next';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
|
@ -13,6 +13,7 @@ import { BLOCK_ACTIONS, STATUS_COLORS } from '../../helpers/constants';
|
||||||
import { toggleClientBlock } from '../../actions/access';
|
import { toggleClientBlock } from '../../actions/access';
|
||||||
import { renderFormattedClientCell } from '../../helpers/renderFormattedClientCell';
|
import { renderFormattedClientCell } from '../../helpers/renderFormattedClientCell';
|
||||||
import { getStats } from '../../actions/stats';
|
import { getStats } from '../../actions/stats';
|
||||||
|
import IconTooltip from '../Logs/Cells/IconTooltip';
|
||||||
|
|
||||||
const getClientsPercentColor = (percent) => {
|
const getClientsPercentColor = (percent) => {
|
||||||
if (percent > 50) {
|
if (percent > 50) {
|
||||||
|
@ -40,9 +41,7 @@ const renderBlockingButton = (ip, disallowed, disallowed_rule) => {
|
||||||
const processingSet = useSelector((state) => state.access.processingSet);
|
const processingSet = useSelector((state) => state.access.processingSet);
|
||||||
const allowedСlients = useSelector((state) => state.access.allowed_clients, shallowEqual);
|
const allowedСlients = useSelector((state) => state.access.allowed_clients, shallowEqual);
|
||||||
|
|
||||||
const buttonClass = classNames('button-action button-action--main', {
|
const [isOptionsOpened, setOptionsOpened] = useState(false);
|
||||||
'button-action--unblock': disallowed,
|
|
||||||
});
|
|
||||||
|
|
||||||
const toggleClientStatus = async (ip, disallowed, disallowed_rule) => {
|
const toggleClientStatus = async (ip, disallowed, disallowed_rule) => {
|
||||||
let confirmMessage;
|
let confirmMessage;
|
||||||
|
@ -62,23 +61,49 @@ const renderBlockingButton = (ip, disallowed, disallowed_rule) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onClick = () => toggleClientStatus(ip, disallowed, disallowed_rule);
|
const onClick = () => {
|
||||||
|
toggleClientStatus(ip, disallowed, disallowed_rule);
|
||||||
|
setOptionsOpened(false);
|
||||||
|
};
|
||||||
|
|
||||||
const text = disallowed ? BLOCK_ACTIONS.UNBLOCK : BLOCK_ACTIONS.BLOCK;
|
const text = disallowed ? BLOCK_ACTIONS.UNBLOCK : BLOCK_ACTIONS.BLOCK;
|
||||||
|
|
||||||
const lastRuleInAllowlist = !disallowed && allowedСlients === disallowed_rule;
|
const lastRuleInAllowlist = !disallowed && allowedСlients === disallowed_rule;
|
||||||
const disabled = processingSet || lastRuleInAllowlist;
|
const disabled = processingSet || lastRuleInAllowlist;
|
||||||
return (
|
return (
|
||||||
<div className="table__action pl-4">
|
<div className="table__action">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={buttonClass}
|
className="btn btn-icon btn-sm px-0"
|
||||||
onClick={onClick}
|
onClick={() => setOptionsOpened(true)}
|
||||||
disabled={disabled}
|
|
||||||
title={lastRuleInAllowlist ? t('last_rule_in_allowlist', { disallowed_rule }) : ''}
|
|
||||||
>
|
>
|
||||||
<Trans>{text}</Trans>
|
<svg className="icon24 icon--lightgray button-action__icon">
|
||||||
|
<use xlinkHref="#bullets" />
|
||||||
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
{isOptionsOpened && (
|
||||||
|
<IconTooltip
|
||||||
|
className="icon24"
|
||||||
|
tooltipClass="button-action--arrow-option-container"
|
||||||
|
xlinkHref="bullets"
|
||||||
|
triggerClass="btn btn-icon btn-sm px-0 button-action__hidden-trigger"
|
||||||
|
content={(
|
||||||
|
<button
|
||||||
|
className={classNames('button-action--arrow-option px-4 py-1', disallowed ? 'bg--green' : 'bg--danger')}
|
||||||
|
onClick={onClick}
|
||||||
|
disabled={disabled}
|
||||||
|
title={lastRuleInAllowlist ? t('last_rule_in_allowlist', { disallowed_rule }) : ''}
|
||||||
|
>
|
||||||
|
<Trans>{text}</Trans>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
placement="bottom-end"
|
||||||
|
trigger="click"
|
||||||
|
onVisibilityChange={setOptionsOpened}
|
||||||
|
defaultTooltipShown={true}
|
||||||
|
delayHide={0}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,11 +28,13 @@
|
||||||
border-bottom: 6px solid #585965;
|
border-bottom: 6px solid #585965;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1279.98px) {
|
.table__action {
|
||||||
.table__action {
|
position: relative;
|
||||||
position: absolute;
|
margin-left: auto;
|
||||||
right: 0;
|
}
|
||||||
}
|
|
||||||
|
.table__action .btn-icon {
|
||||||
|
margin: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-title--dashboard {
|
.page-title--dashboard {
|
||||||
|
|
|
@ -26,9 +26,7 @@ const ClientCell = ({
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const autoClients = useSelector((state) => state.dashboard.autoClients, shallowEqual);
|
const autoClients = useSelector((state) => state.dashboard.autoClients, shallowEqual);
|
||||||
const processingRules = useSelector((state) => state.filtering.processingRules);
|
|
||||||
const isDetailed = useSelector((state) => state.queryLogs.isDetailed);
|
const isDetailed = useSelector((state) => state.queryLogs.isDetailed);
|
||||||
const processingSet = useSelector((state) => state.access.processingSet);
|
|
||||||
const allowedСlients = useSelector((state) => state.access.allowed_clients, shallowEqual);
|
const allowedСlients = useSelector((state) => state.access.allowed_clients, shallowEqual);
|
||||||
const [isOptionsOpened, setOptionsOpened] = useState(false);
|
const [isOptionsOpened, setOptionsOpened] = useState(false);
|
||||||
|
|
||||||
|
@ -84,11 +82,23 @@ const ClientCell = ({
|
||||||
const blockingForClientKey = isFiltered ? 'unblock_for_this_client_only' : 'block_for_this_client_only';
|
const blockingForClientKey = isFiltered ? 'unblock_for_this_client_only' : 'block_for_this_client_only';
|
||||||
const clientNameBlockingFor = getBlockingClientName(clients, client);
|
const clientNameBlockingFor = getBlockingClientName(clients, client);
|
||||||
|
|
||||||
|
const onClick = async () => {
|
||||||
|
await dispatch(toggleBlocking(buttonType, domain));
|
||||||
|
await dispatch(getStats());
|
||||||
|
setOptionsOpened(false);
|
||||||
|
};
|
||||||
|
|
||||||
const BUTTON_OPTIONS = [
|
const BUTTON_OPTIONS = [
|
||||||
|
{
|
||||||
|
name: buttonType,
|
||||||
|
onClick,
|
||||||
|
className: isFiltered ? 'bg--green' : 'bg--danger',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: blockingForClientKey,
|
name: blockingForClientKey,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
dispatch(toggleBlockingForClient(buttonType, domain, clientNameBlockingFor));
|
dispatch(toggleBlockingForClient(buttonType, domain, clientNameBlockingFor));
|
||||||
|
setOptionsOpened(false);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -101,27 +111,25 @@ const ClientCell = ({
|
||||||
client_info?.disallowed_rule || '',
|
client_info?.disallowed_rule || '',
|
||||||
));
|
));
|
||||||
await dispatch(updateLogs());
|
await dispatch(updateLogs());
|
||||||
|
setOptionsOpened(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
disabled: processingSet || lastRuleInAllowlist,
|
disabled: lastRuleInAllowlist,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const onClick = async () => {
|
|
||||||
await dispatch(toggleBlocking(buttonType, domain));
|
|
||||||
await dispatch(getStats());
|
|
||||||
};
|
|
||||||
|
|
||||||
const getOptions = (options) => {
|
const getOptions = (options) => {
|
||||||
if (options.length === 0) {
|
if (options.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{options.map(({ name, onClick, disabled }) => (
|
{options.map(({
|
||||||
|
name, onClick, disabled, className,
|
||||||
|
}) => (
|
||||||
<button
|
<button
|
||||||
key={name}
|
key={name}
|
||||||
className="button-action--arrow-option px-4 py-1"
|
className={classNames('button-action--arrow-option px-4 py-1', className)}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
|
@ -134,17 +142,6 @@ const ClientCell = ({
|
||||||
|
|
||||||
const content = getOptions(BUTTON_OPTIONS);
|
const content = getOptions(BUTTON_OPTIONS);
|
||||||
|
|
||||||
const buttonClass = classNames('button-action button-action--main', {
|
|
||||||
'button-action--unblock': isFiltered,
|
|
||||||
'button-action--with-options': content,
|
|
||||||
'button-action--active': isOptionsOpened,
|
|
||||||
});
|
|
||||||
|
|
||||||
const buttonArrowClass = classNames('button-action button-action--arrow', {
|
|
||||||
'button-action--unblock': isFiltered,
|
|
||||||
'button-action--active': isOptionsOpened,
|
|
||||||
});
|
|
||||||
|
|
||||||
const containerClass = classNames('button-action__container', {
|
const containerClass = classNames('button-action__container', {
|
||||||
'button-action__container--detailed': isDetailed,
|
'button-action__container--detailed': isDetailed,
|
||||||
});
|
});
|
||||||
|
@ -153,25 +150,26 @@ const ClientCell = ({
|
||||||
<div className={containerClass}>
|
<div className={containerClass}>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={buttonClass}
|
className="btn btn-icon btn-sm px-0"
|
||||||
onClick={onClick}
|
onClick={() => setOptionsOpened(true)}
|
||||||
disabled={processingRules}
|
|
||||||
>
|
>
|
||||||
{t(buttonType)}
|
<svg className="icon24 icon--lightgray button-action__icon">
|
||||||
|
<use xlinkHref="#bullets" />
|
||||||
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
{content && (
|
{isOptionsOpened && (
|
||||||
<button className={buttonArrowClass} disabled={processingRules}>
|
<IconTooltip
|
||||||
<IconTooltip
|
className="icon24"
|
||||||
className="icon24"
|
tooltipClass="button-action--arrow-option-container"
|
||||||
tooltipClass="button-action--arrow-option-container"
|
xlinkHref="bullets"
|
||||||
xlinkHref="chevron-down"
|
triggerClass="btn btn-icon btn-sm px-0 button-action__hidden-trigger"
|
||||||
triggerClass="button-action--icon"
|
content={content}
|
||||||
content={content}
|
placement="bottom-end"
|
||||||
placement="bottom-end"
|
trigger="click"
|
||||||
trigger="click"
|
onVisibilityChange={setOptionsOpened}
|
||||||
onVisibilityChange={setOptionsOpened}
|
defaultTooltipShown={true}
|
||||||
/>
|
delayHide={0}
|
||||||
</button>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -198,7 +196,7 @@ const ClientCell = ({
|
||||||
</div>
|
</div>
|
||||||
{isDetailed && clientName && !whoisAvailable && (
|
{isDetailed && clientName && !whoisAvailable && (
|
||||||
<Link
|
<Link
|
||||||
className="detailed-info d-none d-sm-block logs__text logs__text--link"
|
className="detailed-info d-none d-sm-block logs__text logs__text--link logs__text--client"
|
||||||
to={`logs?search="${encodeURIComponent(clientName)}"`}
|
to={`logs?search="${encodeURIComponent(clientName)}"`}
|
||||||
title={clientName}
|
title={clientName}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
.tooltip-custom__container {
|
.tooltip-custom__container {
|
||||||
|
min-width: 150px;
|
||||||
padding: 1rem 1.5rem 1.25rem 1.5rem;
|
padding: 1rem 1.5rem 1.25rem 1.5rem;
|
||||||
font-size: 16px !important;
|
font-size: 16px !important;
|
||||||
box-shadow: 2px 4px 8px rgba(0, 0, 0, 0.2);
|
box-shadow: 2px 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
|
|
@ -21,6 +21,8 @@ const IconTooltip = ({
|
||||||
content,
|
content,
|
||||||
trigger,
|
trigger,
|
||||||
onVisibilityChange,
|
onVisibilityChange,
|
||||||
|
defaultTooltipShown,
|
||||||
|
delayHide,
|
||||||
renderContent = content ? React.Children.map(
|
renderContent = content ? React.Children.map(
|
||||||
processContent(content),
|
processContent(content),
|
||||||
(item, idx) => <div key={idx} className={contentItemClass}>
|
(item, idx) => <div key={idx} className={contentItemClass}>
|
||||||
|
@ -44,6 +46,8 @@ const IconTooltip = ({
|
||||||
trigger={trigger}
|
trigger={trigger}
|
||||||
onVisibilityChange={onVisibilityChange}
|
onVisibilityChange={onVisibilityChange}
|
||||||
delayShow={trigger === 'click' ? 0 : SHOW_TOOLTIP_DELAY}
|
delayShow={trigger === 'click' ? 0 : SHOW_TOOLTIP_DELAY}
|
||||||
|
delayHide={delayHide}
|
||||||
|
defaultTooltipShown={defaultTooltipShown}
|
||||||
>
|
>
|
||||||
{xlinkHref && <svg className={className}>
|
{xlinkHref && <svg className={className}>
|
||||||
<use xlinkHref={`#${xlinkHref}`} />
|
<use xlinkHref={`#${xlinkHref}`} />
|
||||||
|
@ -65,6 +69,8 @@ IconTooltip.propTypes = {
|
||||||
content: PropTypes.node,
|
content: PropTypes.node,
|
||||||
renderContent: PropTypes.arrayOf(PropTypes.element),
|
renderContent: PropTypes.arrayOf(PropTypes.element),
|
||||||
onVisibilityChange: PropTypes.func,
|
onVisibilityChange: PropTypes.func,
|
||||||
|
defaultTooltipShown: PropTypes.bool,
|
||||||
|
delayHide: PropTypes.number,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default IconTooltip;
|
export default IconTooltip;
|
||||||
|
|
|
@ -80,6 +80,10 @@
|
||||||
color: var(--gray-f3);
|
color: var(--gray-f3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logs__text--client {
|
||||||
|
padding-right: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
.icon--selected {
|
.icon--selected {
|
||||||
background-color: var(--gray-f3);
|
background-color: var(--gray-f3);
|
||||||
border: solid 1px var(--gray-d8);
|
border: solid 1px var(--gray-d8);
|
||||||
|
@ -261,9 +265,8 @@
|
||||||
.button-action__container {
|
.button-action__container {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 2px;
|
||||||
bottom: 0.5rem;
|
bottom: 0.5rem;
|
||||||
height: 1.6rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1024px) {
|
@media screen and (max-width: 1024px) {
|
||||||
|
@ -307,45 +310,10 @@
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-action--arrow {
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
border-left: 1px solid var(--white);
|
|
||||||
width: 1.5625rem;
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-action:hover {
|
.button-action:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-action--arrow .button-action--icon {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-action:active {
|
|
||||||
background: var(--btn-block-active);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-action--unblock:active {
|
|
||||||
background: var(--btn-unblock-active);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-action:disabled {
|
|
||||||
background: var(--btn-block-disabled);
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-action--unblock:disabled {
|
|
||||||
background: var(--btn-unblock-disabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-action--arrow-option {
|
.button-action--arrow-option {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
@ -551,3 +519,20 @@
|
||||||
padding: 1rem 1.5rem;
|
padding: 1rem 1.5rem;
|
||||||
background-color: var(--card-bgcolor);
|
background-color: var(--card-bgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-action__hidden-trigger {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 1px;
|
||||||
|
height: 33px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 0;
|
||||||
|
clip: rect(0 0 0 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .button-action__icon {
|
||||||
|
color: var(--gray-f3);
|
||||||
|
}
|
||||||
|
|
|
@ -239,6 +239,12 @@ const Icons = () => (
|
||||||
<circle cx="12" cy="12" r="9" />
|
<circle cx="12" cy="12" r="9" />
|
||||||
<path d="M16.1215 12.1213H11.8789V7.87866" />
|
<path d="M16.1215 12.1213H11.8789V7.87866" />
|
||||||
</symbol>
|
</symbol>
|
||||||
|
|
||||||
|
<symbol id="bullets" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path fillRule="evenodd" clipRule="evenodd" d="M12 7C11.1716 7 10.5 6.32843 10.5 5.5C10.5 4.67157 11.1716 4 12 4C12.8284 4 13.5 4.67157 13.5 5.5C13.5 6.32843 12.8284 7 12 7Z" fill="currentColor" />
|
||||||
|
<path fillRule="evenodd" clipRule="evenodd" d="M12 13.5C11.1716 13.5 10.5 12.8284 10.5 12C10.5 11.1716 11.1716 10.5 12 10.5C12.8284 10.5 13.5 11.1716 13.5 12C13.5 12.8284 12.8284 13.5 12 13.5Z" fill="currentColor" />
|
||||||
|
<path fillRule="evenodd" clipRule="evenodd" d="M12 20C11.1716 20 10.5 19.3284 10.5 18.5C10.5 17.6716 11.1716 17 12 17C12.8284 17 13.5 17.6716 13.5 18.5C13.5 19.3284 12.8284 20 12 20Z" fill="currentColor" />
|
||||||
|
</symbol>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ const Tooltip = ({
|
||||||
delayShow = SHOW_TOOLTIP_DELAY,
|
delayShow = SHOW_TOOLTIP_DELAY,
|
||||||
delayHide = HIDE_TOOLTIP_DELAY,
|
delayHide = HIDE_TOOLTIP_DELAY,
|
||||||
onVisibilityChange,
|
onVisibilityChange,
|
||||||
|
defaultTooltipShown,
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const touchEventsAvailable = 'ontouchstart' in window;
|
const touchEventsAvailable = 'ontouchstart' in window;
|
||||||
|
@ -75,6 +76,7 @@ const Tooltip = ({
|
||||||
delayShow={delayShowValue}
|
delayShow={delayShowValue}
|
||||||
tooltip={renderTooltip}
|
tooltip={renderTooltip}
|
||||||
onVisibilityChange={onVisibilityChange}
|
onVisibilityChange={onVisibilityChange}
|
||||||
|
defaultTooltipShown={defaultTooltipShown}
|
||||||
>
|
>
|
||||||
{renderTrigger}
|
{renderTrigger}
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
@ -97,6 +99,7 @@ Tooltip.propTypes = {
|
||||||
className: propTypes.string,
|
className: propTypes.string,
|
||||||
triggerClass: propTypes.string,
|
triggerClass: propTypes.string,
|
||||||
onVisibilityChange: propTypes.func,
|
onVisibilityChange: propTypes.func,
|
||||||
|
defaultTooltipShown: propTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Tooltip;
|
export default Tooltip;
|
||||||
|
|
|
@ -43,7 +43,7 @@ export const renderFormattedClientCell = (value, info, isDetailed = false, isLog
|
||||||
const whoisAvailable = whois_info && Object.keys(whois_info).length > 0;
|
const whoisAvailable = whois_info && Object.keys(whois_info).length > 0;
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
const nameValue = <div className="logs__text logs__text--link logs__text--nowrap" title={`${name} (${value})`}>
|
const nameValue = <div className="logs__text logs__text--link logs__text--nowrap logs__text--client" title={`${name} (${value})`}>
|
||||||
{name} <small>{`(${value})`}</small>
|
{name} <small>{`(${value})`}</small>
|
||||||
</div>;
|
</div>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue