- client: Use the same tooltip style everywhere
Close #1866
Squashed commit of the following:
commit 3347832caa33b01a0155b212987f02dc4824ab08
Merge: 7766502d d794b11e
Author: ArtemBaskal <a.baskal@adguard.com>
Date: Fri Jul 17 15:12:45 2020 +0300
Merge branch 'master' into fix/1866
commit 7766502d4a904ad0a4d240481f7eabf0e25cfb62
Author: ArtemBaskal <a.baskal@adguard.com>
Date: Fri Jul 17 12:16:59 2020 +0300
Fix icon color classes
commit 90191bf74b5eb1855c733c226f7acb4e906c7ad9
Author: ArtemBaskal <a.baskal@adguard.com>
Date: Fri Jul 17 11:46:22 2020 +0300
Use logs icons, use pointer cursor, fix review markup formatting
commit 0ba50fcd956101f5054ce38c2329df3e8abdfcd2
Author: ArtemBaskal <a.baskal@adguard.com>
Date: Thu Jul 16 18:05:30 2020 +0300
Use help cursor on tooltips
commit bf4e14afe69f874d29be73d8cd4cfbe240ca0304
Author: ArtemBaskal <a.baskal@adguard.com>
Date: Thu Jul 16 17:41:47 2020 +0300
Use tooltip in logs, rename tooltip classes
commit 00568fdc8e8484c5bae67c51ee8189a3a558e219
Author: ArtemBaskal <a.baskal@adguard.com>
Date: Thu Jul 16 17:01:49 2020 +0300
- client: Use the same tooltip style everywhere
This commit is contained in:
parent
d794b11e7a
commit
7d2c7a61f1
|
@ -4,10 +4,10 @@ import { Trans, useTranslation } from 'react-i18next';
|
||||||
import round from 'lodash/round';
|
import round from 'lodash/round';
|
||||||
import { shallowEqual, useSelector } from 'react-redux';
|
import { shallowEqual, useSelector } from 'react-redux';
|
||||||
import Card from '../ui/Card';
|
import Card from '../ui/Card';
|
||||||
import IconTooltip from '../ui/IconTooltip';
|
|
||||||
import { formatNumber } from '../../helpers/helpers';
|
import { formatNumber } from '../../helpers/helpers';
|
||||||
import LogsSearchLink from '../ui/LogsSearchLink';
|
import LogsSearchLink from '../ui/LogsSearchLink';
|
||||||
import { RESPONSE_FILTER } from '../../helpers/constants';
|
import { RESPONSE_FILTER } from '../../helpers/constants';
|
||||||
|
import Tooltip from '../ui/Tooltip';
|
||||||
|
|
||||||
const Row = ({
|
const Row = ({
|
||||||
label, count, response_status, tooltipTitle, translationComponents,
|
label, count, response_status, tooltipTitle, translationComponents,
|
||||||
|
@ -19,7 +19,12 @@ const Row = ({
|
||||||
return <tr key={label}>
|
return <tr key={label}>
|
||||||
<td>
|
<td>
|
||||||
<Trans components={translationComponents}>{label}</Trans>
|
<Trans components={translationComponents}>{label}</Trans>
|
||||||
<IconTooltip text={tooltipTitle} type="tooltip-custom--narrow" />
|
<Tooltip content={tooltipTitle} placement="top"
|
||||||
|
className="tooltip-container tooltip-custom--narrow text-center">
|
||||||
|
<svg className="icons icon--20 icon--lightgray ml-1">
|
||||||
|
<use xlinkHref="#question" />
|
||||||
|
</svg>
|
||||||
|
</Tooltip>
|
||||||
</td>
|
</td>
|
||||||
<td className="text-right"><strong>{content}</strong></td>
|
<td className="text-right"><strong>{content}</strong></td>
|
||||||
</tr>;
|
</tr>;
|
||||||
|
|
|
@ -1,18 +1,67 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import { getTrackerData } from '../../helpers/trackers/trackers';
|
import { Trans } from 'react-i18next';
|
||||||
import Popover from '../ui/Popover';
|
import { getSourceData, getTrackerData } from '../../helpers/trackers/trackers';
|
||||||
|
import Tooltip from '../ui/Tooltip';
|
||||||
|
import { captitalizeWords } from '../../helpers/helpers';
|
||||||
|
|
||||||
|
const renderLabel = (value) => <strong><Trans>{value}</Trans></strong>;
|
||||||
|
|
||||||
|
const renderLink = ({ url, name }) => <a
|
||||||
|
className="tooltip-custom__content-link"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
href={url}
|
||||||
|
>
|
||||||
|
<strong>{name}</strong>
|
||||||
|
</a>;
|
||||||
|
|
||||||
|
|
||||||
|
const getTrackerInfo = (trackerData) => [{
|
||||||
|
key: 'name_table_header',
|
||||||
|
value: trackerData,
|
||||||
|
render: renderLink,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'category_label',
|
||||||
|
value: captitalizeWords(trackerData.category),
|
||||||
|
render: renderLabel,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'source_label',
|
||||||
|
value: getSourceData(trackerData),
|
||||||
|
render: renderLink,
|
||||||
|
}];
|
||||||
|
|
||||||
const DomainCell = ({ value }) => {
|
const DomainCell = ({ value }) => {
|
||||||
const trackerData = getTrackerData(value);
|
const trackerData = getTrackerData(value);
|
||||||
|
|
||||||
|
const content = trackerData && <div className="popover__list">
|
||||||
|
<div className="tooltip-custom__content-title mb-1">
|
||||||
|
<Trans>found_in_known_domain_db</Trans>
|
||||||
|
</div>
|
||||||
|
{getTrackerInfo(trackerData)
|
||||||
|
.map(({ key, value, render }) => <div
|
||||||
|
key={key}
|
||||||
|
className="tooltip-custom__content-item"
|
||||||
|
>
|
||||||
|
<Trans>{key}</Trans>: {render(value)}
|
||||||
|
</div>)}
|
||||||
|
</div>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="logs__row">
|
<div className="logs__row">
|
||||||
<div className="logs__text" title={value}>
|
<div className="logs__text" title={value}>
|
||||||
{value}
|
{value}
|
||||||
</div>
|
</div>
|
||||||
{trackerData && <Popover data={trackerData} />}
|
{trackerData
|
||||||
|
&& <Tooltip content={content} placement="top"
|
||||||
|
className="tooltip-container tooltip-custom--wide">
|
||||||
|
<svg className="icons icon--24 icon--green ml-1">
|
||||||
|
<use xlinkHref="#privacy" />
|
||||||
|
</svg>
|
||||||
|
</Tooltip>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -21,4 +70,9 @@ DomainCell.propTypes = {
|
||||||
value: PropTypes.string.isRequired,
|
value: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
renderLink.propTypes = {
|
||||||
|
url: PropTypes.string.isRequired,
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
export default DomainCell;
|
export default DomainCell;
|
||||||
|
|
|
@ -63,11 +63,11 @@ class Table extends Component {
|
||||||
defaultPageSize={10}
|
defaultPageSize={10}
|
||||||
minRows={5}
|
minRows={5}
|
||||||
previousText={
|
previousText={
|
||||||
<svg className="icons icon--small icon--gray">
|
<svg className="icons icon--24 icon--gray">
|
||||||
<use xlinkHref="#arrow-left" />
|
<use xlinkHref="#arrow-left" />
|
||||||
</svg>}
|
</svg>}
|
||||||
nextText={
|
nextText={
|
||||||
<svg className="icons icon--small icon--gray">
|
<svg className="icons icon--24 icon--gray">
|
||||||
<use xlinkHref="#arrow-right" />
|
<use xlinkHref="#arrow-right" />
|
||||||
</svg>}
|
</svg>}
|
||||||
loadingText={t('loading_table_status')}
|
loadingText={t('loading_table_status')}
|
||||||
|
|
|
@ -139,11 +139,11 @@ class Table extends Component {
|
||||||
noDataText={whitelist ? t('no_whitelist_added') : t('no_blocklist_added')}
|
noDataText={whitelist ? t('no_whitelist_added') : t('no_blocklist_added')}
|
||||||
getPaginationProps={() => ({ className: 'custom-pagination' })}
|
getPaginationProps={() => ({ className: 'custom-pagination' })}
|
||||||
previousText={
|
previousText={
|
||||||
<svg className="icons icon--small icon--gray w-100 h-100">
|
<svg className="icons icon--24 icon--gray w-100 h-100">
|
||||||
<use xlinkHref="#arrow-left" />
|
<use xlinkHref="#arrow-left" />
|
||||||
</svg>}
|
</svg>}
|
||||||
nextText={
|
nextText={
|
||||||
<svg className="icons icon--small icon--gray w-100 h-100">
|
<svg className="icons icon--24 icon--gray w-100 h-100">
|
||||||
<use xlinkHref="#arrow-right" />
|
<use xlinkHref="#arrow-right" />
|
||||||
</svg>}
|
</svg>}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.nav-tabs .nav-link.active {
|
.nav-tabs .nav-link.active {
|
||||||
border-color: #66b574;
|
border-color: var(--green-74);
|
||||||
color: #66b574;
|
color: var(--green-74);
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
.nav-tabs .nav-link.active .nav-icon,
|
.nav-tabs .nav-link.active .nav-icon,
|
||||||
.nav-tabs .nav-item.show .nav-icon {
|
.nav-tabs .nav-item.show .nav-icon {
|
||||||
stroke: #66b574;
|
stroke: var(--green-74);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs .nav-link.active:hover .nav-icon,
|
.nav-tabs .nav-link.active:hover .nav-icon,
|
||||||
|
@ -74,9 +74,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs .nav-item.show .nav-link {
|
.nav-tabs .nav-item.show .nav-link {
|
||||||
color: #66b574;
|
color: var(--green-74);
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-bottom-color: #66b574;
|
border-bottom-color: var(--green-74);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__right {
|
.header__right {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.tooltip__container {
|
.tooltip-custom__container {
|
||||||
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);
|
|
@ -3,7 +3,7 @@ import { nanoid } from 'nanoid';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { formatClientCell } from '../../../helpers/formatClientCell';
|
import { formatClientCell } from '../../../helpers/formatClientCell';
|
||||||
import getHintElement from './getHintElement';
|
import getIconTooltip from './getIconTooltip';
|
||||||
import { checkFiltered } from '../../../helpers/helpers';
|
import { checkFiltered } from '../../../helpers/helpers';
|
||||||
import { BLOCK_ACTIONS } from '../../../helpers/constants';
|
import { BLOCK_ACTIONS } from '../../../helpers/constants';
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ const getClientCell = ({
|
||||||
'white-space--nowrap': isDetailed,
|
'white-space--nowrap': isDetailed,
|
||||||
});
|
});
|
||||||
|
|
||||||
const hintClass = classNames('icons mr-4 icon--small cursor--pointer icon--light-gray', {
|
const hintClass = classNames('icons mr-4 icon--24 icon--lightgray', {
|
||||||
'my-3': isDetailed,
|
'my-3': isDetailed,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ const getClientCell = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="logs__row o-hidden h-100">
|
<div className="logs__row o-hidden h-100">
|
||||||
{getHintElement({
|
{getIconTooltip({
|
||||||
className: hintClass,
|
className: hintClass,
|
||||||
columnClass: 'grid grid--limited',
|
columnClass: 'grid grid--limited',
|
||||||
tooltipClass: 'px-5 pb-5 pt-4 mw-75',
|
tooltipClass: 'px-5 pb-5 pt-4 mw-75',
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import getHintElement from './getHintElement';
|
import getIconTooltip from './getIconTooltip';
|
||||||
import {
|
import {
|
||||||
DEFAULT_SHORT_DATE_FORMAT_OPTIONS,
|
DEFAULT_SHORT_DATE_FORMAT_OPTIONS,
|
||||||
LONG_TIME_FORMAT,
|
LONG_TIME_FORMAT,
|
||||||
|
@ -21,14 +21,14 @@ const getDomainCell = (props) => {
|
||||||
|
|
||||||
const hasTracker = !!tracker;
|
const hasTracker = !!tracker;
|
||||||
|
|
||||||
const lockIconClass = classNames('icons icon--small d-none d-sm-block cursor--pointer', {
|
const lockIconClass = classNames('icons icon--24 d-none d-sm-block', {
|
||||||
'icon--active': answer_dnssec,
|
'icon--green': answer_dnssec,
|
||||||
'icon--disabled': !answer_dnssec,
|
'icon--disabled': !answer_dnssec,
|
||||||
'my-3': isDetailed,
|
'my-3': isDetailed,
|
||||||
});
|
});
|
||||||
|
|
||||||
const privacyIconClass = classNames('icons mx-2 icon--small d-none d-sm-block cursor--pointer', {
|
const privacyIconClass = classNames('icons mx-2 icon--24 d-none d-sm-block', {
|
||||||
'icon--active': hasTracker,
|
'icon--green': hasTracker,
|
||||||
'icon--disabled': !hasTracker,
|
'icon--disabled': !hasTracker,
|
||||||
'my-3': isDetailed,
|
'my-3': isDetailed,
|
||||||
});
|
});
|
||||||
|
@ -72,7 +72,7 @@ const getDomainCell = (props) => {
|
||||||
|
|
||||||
const renderContent = hasTracker ? requestDetails.concat(getGrid(knownTrackerDataObj, 'known_tracker', 'pt-4')) : requestDetails;
|
const renderContent = hasTracker ? requestDetails.concat(getGrid(knownTrackerDataObj, 'known_tracker', 'pt-4')) : requestDetails;
|
||||||
|
|
||||||
const trackerHint = getHintElement({
|
const trackerHint = getIconTooltip({
|
||||||
className: privacyIconClass,
|
className: privacyIconClass,
|
||||||
tooltipClass: 'pt-4 pb-5 px-5 mw-75',
|
tooltipClass: 'pt-4 pb-5 px-5 mw-75',
|
||||||
xlinkHref: 'privacy',
|
xlinkHref: 'privacy',
|
||||||
|
@ -90,7 +90,7 @@ const getDomainCell = (props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="logs__row o-hidden">
|
<div className="logs__row o-hidden">
|
||||||
{dnssec_enabled && getHintElement({
|
{dnssec_enabled && getIconTooltip({
|
||||||
className: lockIconClass,
|
className: lockIconClass,
|
||||||
tooltipClass: 'py-4 px-5 pb-45',
|
tooltipClass: 'py-4 px-5 pb-45',
|
||||||
canShowTooltip: answer_dnssec,
|
canShowTooltip: answer_dnssec,
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import TooltipTrigger from 'react-popper-tooltip';
|
|
||||||
import { Trans } from 'react-i18next';
|
import { Trans } from 'react-i18next';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import './Tooltip.css';
|
|
||||||
import 'react-popper-tooltip/dist/styles.css';
|
|
||||||
import { HIDE_TOOLTIP_DELAY } from '../../../helpers/constants';
|
|
||||||
import { processContent } from '../../../helpers/helpers';
|
import { processContent } from '../../../helpers/helpers';
|
||||||
|
import Tooltip from '../../ui/Tooltip';
|
||||||
|
import 'react-popper-tooltip/dist/styles.css';
|
||||||
|
import './IconTooltip.css';
|
||||||
|
|
||||||
const getHintElement = ({
|
const getIconTooltip = ({
|
||||||
className,
|
className,
|
||||||
contentItemClass,
|
contentItemClass,
|
||||||
columnClass,
|
columnClass,
|
||||||
|
@ -24,30 +23,27 @@ const getHintElement = ({
|
||||||
<Trans>{item || '—'}</Trans>
|
<Trans>{item || '—'}</Trans>
|
||||||
</div>,
|
</div>,
|
||||||
) : null,
|
) : null,
|
||||||
}) => <TooltipTrigger placement={placement} trigger="hover" delayHide={HIDE_TOOLTIP_DELAY} tooltip={
|
}) => {
|
||||||
({
|
const tooltipContent = <>
|
||||||
tooltipRef,
|
{title
|
||||||
getTooltipProps,
|
&& <div className="pb-4 h-25 grid-content font-weight-bold"><Trans>{title}</Trans></div>}
|
||||||
}) => <div {...getTooltipProps({
|
|
||||||
ref: tooltipRef,
|
|
||||||
className: classNames('tooltip__container', tooltipClass, { 'd-none': !canShowTooltip }),
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
{title && <div className="pb-4 h-25 grid-content font-weight-bold">
|
|
||||||
<Trans>{title}</Trans>
|
|
||||||
</div>}
|
|
||||||
<div className={classNames(columnClass)}>{renderContent}</div>
|
<div className={classNames(columnClass)}>{renderContent}</div>
|
||||||
</div>
|
</>;
|
||||||
}>{({
|
|
||||||
getTriggerProps, triggerRef,
|
const tooltipClassName = classNames('tooltip-custom__container', tooltipClass, { 'd-none': !canShowTooltip });
|
||||||
}) => <span {...getTriggerProps({ ref: triggerRef })}>
|
|
||||||
|
return <Tooltip
|
||||||
|
className={tooltipClassName}
|
||||||
|
content={tooltipContent}
|
||||||
|
placement={placement}
|
||||||
|
>
|
||||||
{xlinkHref && <svg className={className}>
|
{xlinkHref && <svg className={className}>
|
||||||
<use xlinkHref={`#${xlinkHref}`} />
|
<use xlinkHref={`#${xlinkHref}`} />
|
||||||
</svg>}
|
</svg>}
|
||||||
</span>}
|
</Tooltip>;
|
||||||
</TooltipTrigger>;
|
};
|
||||||
|
|
||||||
getHintElement.propTypes = {
|
getIconTooltip.propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
contentItemClass: PropTypes.string,
|
contentItemClass: PropTypes.string,
|
||||||
columnClass: PropTypes.string,
|
columnClass: PropTypes.string,
|
||||||
|
@ -63,4 +59,4 @@ getHintElement.propTypes = {
|
||||||
renderContent: PropTypes.arrayOf(PropTypes.element),
|
renderContent: PropTypes.arrayOf(PropTypes.element),
|
||||||
};
|
};
|
||||||
|
|
||||||
export default getHintElement;
|
export default getIconTooltip;
|
|
@ -5,7 +5,7 @@ import {
|
||||||
FILTERED_STATUS,
|
FILTERED_STATUS,
|
||||||
FILTERED_STATUS_TO_META_MAP,
|
FILTERED_STATUS_TO_META_MAP,
|
||||||
} from '../../../helpers/constants';
|
} from '../../../helpers/constants';
|
||||||
import getHintElement from './getHintElement';
|
import getIconTooltip from './getIconTooltip';
|
||||||
|
|
||||||
const getResponseCell = (row, filtering, t, isDetailed, getFilterName) => {
|
const getResponseCell = (row, filtering, t, isDetailed, getFilterName) => {
|
||||||
const {
|
const {
|
||||||
|
@ -95,8 +95,8 @@ const getResponseCell = (row, filtering, t, isDetailed, getFilterName) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="logs__row">
|
<div className="logs__row">
|
||||||
{getHintElement({
|
{getIconTooltip({
|
||||||
className: classNames('icons mr-4 icon--small cursor--pointer icon--light-gray', { 'my-3': isDetailed }),
|
className: classNames('icons mr-4 icon--24 icon--lightgray', { 'my-3': isDetailed }),
|
||||||
columnClass: 'grid grid--limited',
|
columnClass: 'grid grid--limited',
|
||||||
tooltipClass: 'px-5 pb-5 pt-4 mw-75 custom-tooltip__response-details',
|
tooltipClass: 'px-5 pb-5 pt-4 mw-75 custom-tooltip__response-details',
|
||||||
contentItemClass: 'text-truncate key-colon o-hidden',
|
contentItemClass: 'text-truncate key-colon o-hidden',
|
||||||
|
|
|
@ -12,10 +12,10 @@ import {
|
||||||
RESPONSE_FILTER,
|
RESPONSE_FILTER,
|
||||||
RESPONSE_FILTER_QUERIES,
|
RESPONSE_FILTER_QUERIES,
|
||||||
} from '../../../helpers/constants';
|
} from '../../../helpers/constants';
|
||||||
import IconTooltip from '../../ui/IconTooltip';
|
|
||||||
import { setLogsFilter } from '../../../actions/queryLogs';
|
import { setLogsFilter } from '../../../actions/queryLogs';
|
||||||
import useDebounce from '../../../helpers/useDebounce';
|
import useDebounce from '../../../helpers/useDebounce';
|
||||||
import { createOnBlurHandler, getLogsUrlParams } from '../../../helpers/helpers';
|
import { createOnBlurHandler, getLogsUrlParams } from '../../../helpers/helpers';
|
||||||
|
import Tooltip from '../../ui/Tooltip';
|
||||||
|
|
||||||
const renderFilterField = ({
|
const renderFilterField = ({
|
||||||
input,
|
input,
|
||||||
|
@ -35,7 +35,7 @@ const renderFilterField = ({
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<div className="input-group-search input-group-search__icon--magnifier">
|
<div className="input-group-search input-group-search__icon--magnifier">
|
||||||
<svg className="icons icon--small icon--gray">
|
<svg className="icons icon--24 icon--gray">
|
||||||
<use xlinkHref="#magnifier" />
|
<use xlinkHref="#magnifier" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
@ -53,12 +53,16 @@ const renderFilterField = ({
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={classNames('input-group-search input-group-search__icon--cross', { invisible: input.value.length < 1 })}>
|
className={classNames('input-group-search input-group-search__icon--cross', { invisible: input.value.length < 1 })}>
|
||||||
<svg className="icons icon--smallest icon--gray" onClick={onClearInputClick}>
|
<svg className="icons icon--20 icon--gray" onClick={onClearInputClick}>
|
||||||
<use xlinkHref="#cross" />
|
<use xlinkHref="#cross" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<span className="input-group-search input-group-search__icon--tooltip">
|
<span className="input-group-search input-group-search__icon--tooltip">
|
||||||
<IconTooltip text={tooltip} type='tooltip-custom--logs' />
|
<Tooltip content={tooltip} className="tooltip-container">
|
||||||
|
<svg className="icons icon--20 icon--gray">
|
||||||
|
<use xlinkHref="#question" />
|
||||||
|
</svg>
|
||||||
|
</Tooltip>
|
||||||
</span>
|
</span>
|
||||||
{!disabled
|
{!disabled
|
||||||
&& touched
|
&& touched
|
||||||
|
|
|
@ -12,7 +12,7 @@ const Filters = ({ filter, refreshLogs, setIsLoading }) => (
|
||||||
className="btn btn-icon--green ml-3 bg-transparent"
|
className="btn btn-icon--green ml-3 bg-transparent"
|
||||||
onClick={refreshLogs}
|
onClick={refreshLogs}
|
||||||
>
|
>
|
||||||
<svg className="icons icon--small">
|
<svg className="icons icon--24">
|
||||||
<use xlinkHref="#update" />
|
<use xlinkHref="#update" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -399,10 +399,6 @@
|
||||||
top: 0.5rem;
|
top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon--light-gray {
|
|
||||||
color: var(--gray-8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.link--green {
|
.link--green {
|
||||||
color: var(--green79);
|
color: var(--green79);
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,27 +154,23 @@ const Table = (props) => {
|
||||||
headerClassName: 'logs__text',
|
headerClassName: 'logs__text',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: () => {
|
Header: function Header() {
|
||||||
const plainSelected = classNames('cursor--pointer', {
|
|
||||||
'icon--selected': !isDetailed,
|
|
||||||
});
|
|
||||||
|
|
||||||
const detailedSelected = classNames('cursor--pointer', {
|
|
||||||
'icon--selected': isDetailed,
|
|
||||||
});
|
|
||||||
|
|
||||||
return <div className="d-flex justify-content-between">
|
return <div className="d-flex justify-content-between">
|
||||||
{t('client_table_header')}
|
{t('client_table_header')}
|
||||||
{<span>
|
{<span>
|
||||||
<svg
|
<svg
|
||||||
className={`icons icon--small icon--active mr-2 cursor--pointer ${plainSelected}`}
|
className={classNames('icons icon--24 icon--green mr-2 cursor--pointer', {
|
||||||
|
'icon--selected': !isDetailed,
|
||||||
|
})}
|
||||||
onClick={() => toggleDetailedLogs(false)}
|
onClick={() => toggleDetailedLogs(false)}
|
||||||
>
|
>
|
||||||
<title><Trans>compact</Trans></title>
|
<title><Trans>compact</Trans></title>
|
||||||
<use xlinkHref='#list' />
|
<use xlinkHref='#list' />
|
||||||
</svg>
|
</svg>
|
||||||
<svg
|
<svg
|
||||||
className={`icons icon--small icon--active cursor--pointer ${detailedSelected}`}
|
className={classNames('icons icon--24 icon--green cursor--pointer', {
|
||||||
|
'icon--selected': isDetailed,
|
||||||
|
})}
|
||||||
onClick={() => toggleDetailedLogs(true)}
|
onClick={() => toggleDetailedLogs(true)}
|
||||||
>
|
>
|
||||||
<title><Trans>default</Trans></title>
|
<title><Trans>default</Trans></title>
|
||||||
|
@ -261,12 +257,12 @@ const Table = (props) => {
|
||||||
getPaginationProps={() => ({ className: 'custom-pagination custom-pagination--padding' })}
|
getPaginationProps={() => ({ className: 'custom-pagination custom-pagination--padding' })}
|
||||||
getTbodyProps={() => ({ className: 'd-block' })}
|
getTbodyProps={() => ({ className: 'd-block' })}
|
||||||
previousText={
|
previousText={
|
||||||
<svg className="icons icon--small icon--gray w-100 h-100 cursor--pointer">
|
<svg className="icons icon--24 icon--gray w-100 h-100 cursor--pointer">
|
||||||
<title><Trans>previous_btn</Trans></title>
|
<title><Trans>previous_btn</Trans></title>
|
||||||
<use xlinkHref="#arrow-left" />
|
<use xlinkHref="#arrow-left" />
|
||||||
</svg>}
|
</svg>}
|
||||||
nextText={
|
nextText={
|
||||||
<svg className="icons icon--small icon--gray w-100 h-100 cursor--pointer">
|
<svg className="icons icon--24 icon--gray w-100 h-100 cursor--pointer">
|
||||||
<title><Trans>next_btn</Trans></title>
|
<title><Trans>next_btn</Trans></title>
|
||||||
<use xlinkHref="#arrow-right" />
|
<use xlinkHref="#arrow-right" />
|
||||||
</svg>}
|
</svg>}
|
||||||
|
|
|
@ -245,7 +245,7 @@ const Logs = (props) => {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
className="icon icon--small icon-cross d-block d-md-none cursor--pointer"
|
className="icon icon--24 icon-cross d-block d-md-none cursor--pointer"
|
||||||
onClick={closeModal}>
|
onClick={closeModal}>
|
||||||
<use xlinkHref="#cross" />
|
<use xlinkHref="#cross" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
@ -89,11 +89,11 @@ class AutoClients extends Component {
|
||||||
showPageJump={false}
|
showPageJump={false}
|
||||||
renderTotalPagesCount={() => false}
|
renderTotalPagesCount={() => false}
|
||||||
previousText={
|
previousText={
|
||||||
<svg className="icons icon--small icon--gray w-100 h-100">
|
<svg className="icons icon--24 icon--gray w-100 h-100">
|
||||||
<use xlinkHref="#arrow-left" />
|
<use xlinkHref="#arrow-left" />
|
||||||
</svg>}
|
</svg>}
|
||||||
nextText={
|
nextText={
|
||||||
<svg className="icons icon--small icon--gray w-100 h-100">
|
<svg className="icons icon--24 icon--gray w-100 h-100">
|
||||||
<use xlinkHref="#arrow-right" />
|
<use xlinkHref="#arrow-right" />
|
||||||
</svg>}
|
</svg>}
|
||||||
loadingText={t('loading_table_status')}
|
loadingText={t('loading_table_status')}
|
||||||
|
|
|
@ -301,11 +301,11 @@ class ClientsTable extends Component {
|
||||||
showPageJump={false}
|
showPageJump={false}
|
||||||
renderTotalPagesCount={() => false}
|
renderTotalPagesCount={() => false}
|
||||||
previousText={
|
previousText={
|
||||||
<svg className="icons icon--small icon--gray w-100 h-100">
|
<svg className="icons icon--24 icon--gray w-100 h-100">
|
||||||
<use xlinkHref="#arrow-left" />
|
<use xlinkHref="#arrow-left" />
|
||||||
</svg>}
|
</svg>}
|
||||||
nextText={
|
nextText={
|
||||||
<svg className="icons icon--small icon--gray w-100 h-100">
|
<svg className="icons icon--24 icon--gray w-100 h-100">
|
||||||
<use xlinkHref="#arrow-right" />
|
<use xlinkHref="#arrow-right" />
|
||||||
</svg>}
|
</svg>}
|
||||||
loadingText={t('loading_table_status')}
|
loadingText={t('loading_table_status')}
|
||||||
|
|
|
@ -88,7 +88,7 @@ const renderFieldsWrapper = (placeholder, buttonTitle) => function cell(row) {
|
||||||
onClick={() => fields.push()}
|
onClick={() => fields.push()}
|
||||||
title={buttonTitle}
|
title={buttonTitle}
|
||||||
>
|
>
|
||||||
<svg className="icon icon--small">
|
<svg className="icon icon--24">
|
||||||
<use xlinkHref="#plus" />
|
<use xlinkHref="#plus" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.dropdown-item.active,
|
.dropdown-item.active,
|
||||||
.dropdown-item:active {
|
.dropdown-item:active {
|
||||||
background-color: #66b574;
|
background-color: var(--green-74);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
.tooltip-custom {
|
|
||||||
position: relative;
|
|
||||||
top: -1px;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
background-image: url("./svg/help-circle.svg");
|
|
||||||
background-size: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip-custom:before {
|
|
||||||
content: attr(data-tooltip);
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
bottom: calc(100% + 10px);
|
|
||||||
left: 50%;
|
|
||||||
padding: 10px 15px;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
text-align: center;
|
|
||||||
color: #fff;
|
|
||||||
background-color: #585965;
|
|
||||||
border-radius: 3px;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
visibility: hidden;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip-custom:after {
|
|
||||||
content: "";
|
|
||||||
position: relative;
|
|
||||||
top: -7px;
|
|
||||||
left: calc(50% - 6px);
|
|
||||||
visibility: hidden;
|
|
||||||
opacity: 0;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-left: 6px solid transparent;
|
|
||||||
border-right: 6px solid transparent;
|
|
||||||
border-top: 6px solid #585965;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip-custom:hover:before,
|
|
||||||
.tooltip-custom:hover:after {
|
|
||||||
visibility: visible;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip-custom--narrow:before {
|
|
||||||
width: 220px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip-custom--logs {
|
|
||||||
border-radius: 50%;
|
|
||||||
background-image: url("./svg/help-circle-gray.svg");
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip-custom--logs:before {
|
|
||||||
bottom: initial;
|
|
||||||
top: calc(100% + 10px);
|
|
||||||
right: -10px;
|
|
||||||
left: initial;
|
|
||||||
width: 255px;
|
|
||||||
transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip-custom--logs:after {
|
|
||||||
top: 8px;
|
|
||||||
border-top: none;
|
|
||||||
border-bottom: 6px solid #585965;
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import './IconTooltip.css';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
const IconTooltip = ({ text, type = '' }) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
return <div data-tooltip={t(text)}
|
|
||||||
className={`tooltip-custom ml-1 ${type}`} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
IconTooltip.propTypes = {
|
|
||||||
text: PropTypes.string.isRequired,
|
|
||||||
type: PropTypes.string,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default IconTooltip;
|
|
|
@ -4,24 +4,36 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon--small {
|
.icon--24 {
|
||||||
width: 1.5rem;
|
--size: 1.5rem;
|
||||||
height: 1.5rem;
|
width: var(--size);
|
||||||
|
height: var(--size);
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon--smallest {
|
.icon--20 {
|
||||||
width: 1.2rem;
|
--size: 1.25rem;
|
||||||
height: 1.2rem;
|
width: var(--size);
|
||||||
|
height: var(--size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon--18 {
|
||||||
|
--size: 1.125rem;
|
||||||
|
width: var(--size);
|
||||||
|
height: var(--size);
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon--gray {
|
.icon--gray {
|
||||||
color: var(--gray-a5);
|
color: var(--gray-a5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon--green {
|
||||||
|
color: var(--green-74);
|
||||||
|
}
|
||||||
|
|
||||||
.icon--disabled {
|
.icon--disabled {
|
||||||
color: var(--gray-d8);
|
color: var(--gray-d8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon--active {
|
.icon--lightgray {
|
||||||
color: #66b574;
|
color: var(--gray-8);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,151 +0,0 @@
|
||||||
.popover-wrap {
|
|
||||||
position: relative;
|
|
||||||
top: 1px;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
align-self: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__trigger {
|
|
||||||
position: relative;
|
|
||||||
top: 3px;
|
|
||||||
margin: 0 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__trigger:after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: -6px;
|
|
||||||
left: -3px;
|
|
||||||
width: 26px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__trigger--address {
|
|
||||||
top: 0;
|
|
||||||
margin: 0;
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__trigger--address:after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__body {
|
|
||||||
content: "";
|
|
||||||
display: flex;
|
|
||||||
position: absolute;
|
|
||||||
bottom: calc(100% + 3px);
|
|
||||||
left: 50%;
|
|
||||||
z-index: 1;
|
|
||||||
min-width: 275px;
|
|
||||||
padding: 10px 15px;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
white-space: normal;
|
|
||||||
color: #fff;
|
|
||||||
background-color: #585965;
|
|
||||||
border-radius: 3px;
|
|
||||||
transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
visibility: hidden;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__body--filter {
|
|
||||||
min-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__body:after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
bottom: -5px;
|
|
||||||
left: calc(50% - 6px);
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-left: 6px solid transparent;
|
|
||||||
border-right: 6px solid transparent;
|
|
||||||
border-top: 6px solid #585965;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__body--address {
|
|
||||||
top: calc(100% + 10px);
|
|
||||||
right: 0;
|
|
||||||
left: initial;
|
|
||||||
bottom: initial;
|
|
||||||
z-index: 1;
|
|
||||||
min-width: 100px;
|
|
||||||
padding: 12px 18px;
|
|
||||||
font-weight: 700;
|
|
||||||
text-align: left;
|
|
||||||
white-space: nowrap;
|
|
||||||
transform: none;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__body--address:after {
|
|
||||||
top: -11px;
|
|
||||||
left: initial;
|
|
||||||
right: 40px;
|
|
||||||
border-top: 6px solid transparent;
|
|
||||||
border-bottom: 6px solid #585965;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__body--address:before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: -7px;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__trigger:hover + .popover__body,
|
|
||||||
.popover__body:hover {
|
|
||||||
visibility: visible;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__icon {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
stroke: #9aa0ac;
|
|
||||||
color: #9aa0ac;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__icon--green {
|
|
||||||
color: #66b574;
|
|
||||||
stroke: #66b574;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__list--bold {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__list-title {
|
|
||||||
margin-bottom: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__list-item {
|
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__list-item--nowrap {
|
|
||||||
max-width: 300px;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__list-item:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__link {
|
|
||||||
color: #66b586;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover__link:hover,
|
|
||||||
.popover__link:focus {
|
|
||||||
color: #66b586;
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
import React, { Component } from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Trans, withTranslation } from 'react-i18next';
|
|
||||||
import { getSourceData } from '../../helpers/trackers/trackers';
|
|
||||||
import { captitalizeWords } from '../../helpers/helpers';
|
|
||||||
|
|
||||||
import './Popover.css';
|
|
||||||
|
|
||||||
class Popover extends Component {
|
|
||||||
render() {
|
|
||||||
const { data } = this.props;
|
|
||||||
|
|
||||||
const sourceData = getSourceData(data);
|
|
||||||
|
|
||||||
const source = (
|
|
||||||
<div className="popover__list-item">
|
|
||||||
<Trans>source_label</Trans>: <a className="popover__link" target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
href={sourceData.url}>
|
|
||||||
<strong>{sourceData.name}</strong>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const tracker = (
|
|
||||||
<div className="popover__list-item">
|
|
||||||
<Trans>name_table_header</Trans>: <a className="popover__link" target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
href={data.url}>
|
|
||||||
<strong>{data.name}</strong>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const categoryName = captitalizeWords(data.category);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="popover-wrap">
|
|
||||||
<div className="popover__trigger">
|
|
||||||
<svg className="popover__icon" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24" fill="none" strokeWidth="2" strokeLinecap="round"
|
|
||||||
strokeLinejoin="round">
|
|
||||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
|
||||||
<circle cx="12" cy="12" r="3"></circle>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div className="popover__body">
|
|
||||||
<div className="popover__list">
|
|
||||||
<div className="popover__list-title">
|
|
||||||
<Trans>found_in_known_domain_db</Trans>
|
|
||||||
</div>
|
|
||||||
{tracker}
|
|
||||||
<div className="popover__list-item">
|
|
||||||
<Trans>category_label</Trans>: <strong>
|
|
||||||
<Trans>{categoryName}</Trans></strong>
|
|
||||||
</div>
|
|
||||||
{source}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Popover.propTypes = {
|
|
||||||
data: PropTypes.object.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default withTranslation()(Popover);
|
|
|
@ -1,52 +0,0 @@
|
||||||
import React, { Component } from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Trans, withTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
import './Popover.css';
|
|
||||||
|
|
||||||
class PopoverFilter extends Component {
|
|
||||||
render() {
|
|
||||||
const { rule, filter, service } = this.props;
|
|
||||||
|
|
||||||
if (!rule && !service) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="popover-wrap">
|
|
||||||
<div className="popover__trigger popover__trigger--filter">
|
|
||||||
<svg className="popover__icon popover__icon--green">
|
|
||||||
<use xlinkHref="#question" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div className="popover__body popover__body--filter">
|
|
||||||
<div className="popover__list">
|
|
||||||
{rule && (
|
|
||||||
<div className="popover__list-item popover__list-item--nowrap">
|
|
||||||
<Trans>rule_label</Trans>: <strong>{rule}</strong>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{filter && (
|
|
||||||
<div className="popover__list-item popover__list-item--nowrap">
|
|
||||||
<Trans>list_label</Trans>: <strong>{filter}</strong>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{service && (
|
|
||||||
<div className="popover__list-item popover__list-item--nowrap">
|
|
||||||
<Trans>blocked_service</Trans>: <strong>{service}</strong>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PopoverFilter.propTypes = {
|
|
||||||
rule: PropTypes.string,
|
|
||||||
filter: PropTypes.string,
|
|
||||||
service: PropTypes.string,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default withTranslation()(PopoverFilter);
|
|
|
@ -19,10 +19,13 @@ Dashboard UI
|
||||||
--orange: #fd9644;
|
--orange: #fd9644;
|
||||||
--yellow: #f1c40f;
|
--yellow: #f1c40f;
|
||||||
--green: #5eba00;
|
--green: #5eba00;
|
||||||
|
--green-74: #66b574;
|
||||||
|
--green-86: #66b586;
|
||||||
--teal: #2bcbba;
|
--teal: #2bcbba;
|
||||||
--cyan: #17a2b8;
|
--cyan: #17a2b8;
|
||||||
--white: #fff;
|
--white: #fff;
|
||||||
--gray: #868e96;
|
--gray: #868e96;
|
||||||
|
--gray-ac: #9aa0ac;
|
||||||
--gray-dark: #343a40;
|
--gray-dark: #343a40;
|
||||||
--azure: #45aaf2;
|
--azure: #45aaf2;
|
||||||
--lime: #7bd235;
|
--lime: #7bd235;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
.tooltip-custom--narrow {
|
||||||
|
max-width: 13.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-custom--wide {
|
||||||
|
max-width: 18rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-custom__trigger {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-custom__content-title {
|
||||||
|
margin-bottom: 0.1875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-custom__content-item {
|
||||||
|
margin-bottom: 0.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-custom__content-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-custom__content-link {
|
||||||
|
color: var(--green-86);
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
import React from 'react';
|
||||||
|
import TooltipTrigger from 'react-popper-tooltip';
|
||||||
|
import propTypes from 'prop-types';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { HIDE_TOOLTIP_DELAY } from '../../helpers/constants';
|
||||||
|
import 'react-popper-tooltip/dist/styles.css';
|
||||||
|
import './Tooltip.css';
|
||||||
|
|
||||||
|
const Tooltip = ({
|
||||||
|
children,
|
||||||
|
content,
|
||||||
|
triggerClass = 'tooltip-custom__trigger',
|
||||||
|
className = 'tooltip-container',
|
||||||
|
placement = 'bottom',
|
||||||
|
trigger = 'hover',
|
||||||
|
delayHide = HIDE_TOOLTIP_DELAY,
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return <TooltipTrigger
|
||||||
|
placement={placement}
|
||||||
|
trigger={trigger}
|
||||||
|
delayHide={delayHide}
|
||||||
|
tooltip={({
|
||||||
|
tooltipRef,
|
||||||
|
getTooltipProps,
|
||||||
|
}) => <div {...getTooltipProps({
|
||||||
|
ref: tooltipRef,
|
||||||
|
className,
|
||||||
|
})}>
|
||||||
|
{typeof content === 'string' ? t(content) : content}
|
||||||
|
</div>
|
||||||
|
}>{({ getTriggerProps, triggerRef }) => <span
|
||||||
|
{...getTriggerProps({
|
||||||
|
ref: triggerRef,
|
||||||
|
className: triggerClass,
|
||||||
|
})}
|
||||||
|
>{children}</span>}
|
||||||
|
</TooltipTrigger>;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tooltip.propTypes = {
|
||||||
|
children: propTypes.element.isRequired,
|
||||||
|
content: propTypes.oneOfType(
|
||||||
|
[
|
||||||
|
propTypes.string,
|
||||||
|
propTypes.element,
|
||||||
|
propTypes.arrayOf(propTypes.element),
|
||||||
|
],
|
||||||
|
).isRequired,
|
||||||
|
placement: propTypes.string,
|
||||||
|
trigger: propTypes.string,
|
||||||
|
delayHide: propTypes.string,
|
||||||
|
className: propTypes.string,
|
||||||
|
triggerClass: propTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Tooltip;
|
|
@ -1 +1,6 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#66b574" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-help-circle"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12" y2="17"></line></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#66b574"
|
||||||
|
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-help-circle">
|
||||||
|
<circle cx="12" cy="12" r="10"></circle>
|
||||||
|
<path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
|
||||||
|
<line x1="12" y1="17" x2="12" y2="17"></line>
|
||||||
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 357 B After Width: | Height: | Size: 379 B |
|
@ -90,7 +90,7 @@ export const renderGroupField = ({
|
||||||
className="btn btn-secondary btn-icon btn-icon--green"
|
className="btn btn-secondary btn-icon btn-icon--green"
|
||||||
onClick={removeField}
|
onClick={removeField}
|
||||||
>
|
>
|
||||||
<svg className="icon icon--small">
|
<svg className="icon icon--24">
|
||||||
<use xlinkHref="#cross" />
|
<use xlinkHref="#cross" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
Loading…
Reference in New Issue