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, getRulesToFilterList, formatDateTime, formatElapsedMs, formatTime, getBlockingClientName, 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'; import { updateLogs } from '../../../actions/queryLogs'; 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 clients = useSelector((state) => state.dashboard.clients); const onClick = () => { if (!isSmallScreen) { return; } const { answer_dnssec, client, domain, elapsedMs, info, info: { disallowed, disallowed_rule }, reason, response, time, tracker, upstream, type, client_proto, rules, 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 { confirmMessage, buttonKey: blockingClientKey, isNotInAllowedList, } = getBlockClientInfo(client, disallowed, disallowed_rule); 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 = async () => { if (window.confirm(confirmMessage)) { await dispatch(toggleClientBlock(client, disallowed, disallowed_rule)); await dispatch(updateLogs()); setModalOpened(false); } }; const blockButton = ; const blockForClientButton = ; const blockClientButton = ; const detailedData = { time_table_header: formatTime(time, LONG_TIME_FORMAT), date: formatDateTime(time, DEFAULT_SHORT_DATE_FORMAT_OPTIONS), encryption_status: isBlocked ?