import React, { memo } from 'react'; import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; import { shallowEqual, useDispatch, useSelector } from 'react-redux'; import propTypes from 'prop-types'; import { captitalizeWords, checkFiltered, formatDateTime, formatElapsedMs, formatTime, getBlockingClientName, getFilterName, getServiceName, processContent, } from '../../../helpers/helpers'; import { BLOCK_ACTIONS, DEFAULT_SHORT_DATE_FORMAT_OPTIONS, FILTERED_STATUS, FILTERED_STATUS_TO_META_MAP, LONG_TIME_FORMAT, QUERY_STATUS_COLORS, SCHEME_TO_PROTOCOL_MAP, } from '../../../helpers/constants'; import { getSourceData } from '../../../helpers/trackers/trackers'; import { toggleBlocking, toggleBlockingForClient } from '../../../actions'; import DateCell from './DateCell'; import DomainCell from './DomainCell'; import ResponseCell from './ResponseCell'; import ClientCell from './ClientCell'; import '../Logs.css'; import { toggleClientBlock } from '../../../actions/access'; import { getBlockClientInfo, BUTTON_PREFIX } from './helpers'; const Row = memo(({ style, rowProps, rowProps: { reason }, isSmallScreen, setDetailedDataCurrent, setButtonType, setModalOpened, }) => { const dispatch = useDispatch(); const { t } = useTranslation(); const dnssec_enabled = useSelector((state) => state.dnsConfig.dnssec_enabled); const filters = useSelector((state) => state.filtering.filters, shallowEqual); const whitelistFilters = useSelector((state) => state.filtering.whitelistFilters, shallowEqual); const autoClients = useSelector((state) => state.dashboard.autoClients, shallowEqual); const disallowed_clients = useSelector( (state) => state.access.disallowed_clients, shallowEqual, ); const clients = useSelector((state) => state.dashboard.clients); const onClick = () => { if (!isSmallScreen) { return; } const { answer_dnssec, client, domain, elapsedMs, info, reason, response, time, tracker, upstream, type, client_proto, filterId, rule, originalResponse, status, service_name, } = rowProps; const hasTracker = !!tracker; const autoClient = autoClients .find((autoClient) => autoClient.name === client); const { whois_info } = info; const country = whois_info?.country; const city = whois_info?.city; const network = whois_info?.orgname; const source = autoClient?.source; const formattedElapsedMs = formatElapsedMs(elapsedMs, t); const isFiltered = checkFiltered(reason); const isBlocked = reason === FILTERED_STATUS.FILTERED_BLACK_LIST || reason === FILTERED_STATUS.FILTERED_BLOCKED_SERVICE; const buttonType = isFiltered ? BLOCK_ACTIONS.UNBLOCK : BLOCK_ACTIONS.BLOCK; const onToggleBlock = () => { dispatch(toggleBlocking(buttonType, domain)); }; const isBlockedByResponse = originalResponse.length > 0 && isBlocked; const requestStatus = t(isBlockedByResponse ? 'blocked_by_cname_or_ip' : FILTERED_STATUS_TO_META_MAP[reason]?.LABEL || reason); const protocol = t(SCHEME_TO_PROTOCOL_MAP[client_proto]) || ''; const sourceData = getSourceData(tracker); const filter = getFilterName(filters, whitelistFilters, filterId); const { confirmMessage, buttonKey: blockingClientKey, type: blockType, } = getBlockClientInfo(client, disallowed_clients); const blockingForClientKey = isFiltered ? 'unblock_for_this_client_only' : 'block_for_this_client_only'; const clientNameBlockingFor = getBlockingClientName(clients, client); const onBlockingForClientClick = () => { dispatch(toggleBlockingForClient(buttonType, domain, clientNameBlockingFor)); }; const onBlockingClientClick = () => { const message = `${blockType === BLOCK_ACTIONS.BLOCK ? t('adg_will_drop_dns_queries') : ''} ${t(confirmMessage, { ip: client })}`; if (window.confirm(message)) { dispatch(toggleClientBlock(blockType, client)); } }; const detailedData = { time_table_header: formatTime(time, LONG_TIME_FORMAT), date: formatDateTime(time, DEFAULT_SHORT_DATE_FORMAT_OPTIONS), encryption_status: isBlocked ?