+ client: handle clients find
This commit is contained in:
parent
a6d6e9ec9e
commit
f8202a74bd
@ -299,10 +299,11 @@
|
|||||||
"client_edit": "Edit Client",
|
"client_edit": "Edit Client",
|
||||||
"client_identifier": "Identifier",
|
"client_identifier": "Identifier",
|
||||||
"ip_address": "IP address",
|
"ip_address": "IP address",
|
||||||
"client_identifier_desc": "Clients can be identified by the IP address, MAC address, CIDR. Please note, that using MAC as identifier is possible only if AdGuard Home is also a <0>DHCP server</0>",
|
"client_identifier_desc": "Clients can be identified by the IP address, CIDR, MAC address. Please note, that using MAC as identifier is possible only if AdGuard Home is also a <0>DHCP server</0>",
|
||||||
"form_enter_ip": "Enter IP",
|
"form_enter_ip": "Enter IP",
|
||||||
"form_enter_mac": "Enter MAC",
|
"form_enter_mac": "Enter MAC",
|
||||||
"form_enter_id": "Enter identifier",
|
"form_enter_id": "Enter identifier",
|
||||||
|
"form_add_id": "Add identifier",
|
||||||
"form_client_name": "Enter client name",
|
"form_client_name": "Enter client name",
|
||||||
"client_global_settings": "Use global settings",
|
"client_global_settings": "Use global settings",
|
||||||
"client_deleted": "Client \"{{key}}\" successfully deleted",
|
"client_deleted": "Client \"{{key}}\" successfully deleted",
|
||||||
|
@ -2,7 +2,7 @@ import { createAction } from 'redux-actions';
|
|||||||
|
|
||||||
import apiClient from '../api/Api';
|
import apiClient from '../api/Api';
|
||||||
import { addErrorToast, addSuccessToast } from './index';
|
import { addErrorToast, addSuccessToast } from './index';
|
||||||
import { normalizeLogs } from '../helpers/helpers';
|
import { normalizeLogs, getParamsForClientsSearch, addClientInfo } from '../helpers/helpers';
|
||||||
import { TABLE_DEFAULT_PAGE_SIZE } from '../helpers/constants';
|
import { TABLE_DEFAULT_PAGE_SIZE } from '../helpers/constants';
|
||||||
|
|
||||||
const getLogsWithParams = async (config) => {
|
const getLogsWithParams = async (config) => {
|
||||||
@ -10,9 +10,12 @@ const getLogsWithParams = async (config) => {
|
|||||||
const rawLogs = await apiClient.getQueryLog({ ...filter, older_than });
|
const rawLogs = await apiClient.getQueryLog({ ...filter, older_than });
|
||||||
const { data, oldest } = rawLogs;
|
const { data, oldest } = rawLogs;
|
||||||
const logs = normalizeLogs(data);
|
const logs = normalizeLogs(data);
|
||||||
|
const clientsParams = getParamsForClientsSearch(logs, 'client');
|
||||||
|
const clients = await apiClient.findClients(clientsParams);
|
||||||
|
const logsWithClientInfo = addClientInfo(logs, clients, 'client');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
logs, oldest, older_than, filter, ...values,
|
logs: logsWithClientInfo, oldest, older_than, filter, ...values,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { createAction } from 'redux-actions';
|
|||||||
|
|
||||||
import apiClient from '../api/Api';
|
import apiClient from '../api/Api';
|
||||||
import { addErrorToast, addSuccessToast } from './index';
|
import { addErrorToast, addSuccessToast } from './index';
|
||||||
import { normalizeTopStats, secondsToMilliseconds } from '../helpers/helpers';
|
import { normalizeTopStats, secondsToMilliseconds, getParamsForClientsSearch, addClientInfo } from '../helpers/helpers';
|
||||||
|
|
||||||
export const getStatsConfigRequest = createAction('GET_STATS_CONFIG_REQUEST');
|
export const getStatsConfigRequest = createAction('GET_STATS_CONFIG_REQUEST');
|
||||||
export const getStatsConfigFailure = createAction('GET_STATS_CONFIG_FAILURE');
|
export const getStatsConfigFailure = createAction('GET_STATS_CONFIG_FAILURE');
|
||||||
@ -43,11 +43,15 @@ export const getStats = () => async (dispatch) => {
|
|||||||
dispatch(getStatsRequest());
|
dispatch(getStatsRequest());
|
||||||
try {
|
try {
|
||||||
const stats = await apiClient.getStats();
|
const stats = await apiClient.getStats();
|
||||||
|
const normalizedTopClients = normalizeTopStats(stats.top_clients);
|
||||||
|
const clientsParams = getParamsForClientsSearch(normalizedTopClients, 'name');
|
||||||
|
const clients = await apiClient.findClients(clientsParams);
|
||||||
|
const topClientsWithInfo = addClientInfo(normalizedTopClients, clients, 'name');
|
||||||
|
|
||||||
const normalizedStats = {
|
const normalizedStats = {
|
||||||
...stats,
|
...stats,
|
||||||
top_blocked_domains: normalizeTopStats(stats.top_blocked_domains),
|
top_blocked_domains: normalizeTopStats(stats.top_blocked_domains),
|
||||||
top_clients: normalizeTopStats(stats.top_clients),
|
top_clients: topClientsWithInfo,
|
||||||
top_queried_domains: normalizeTopStats(stats.top_queried_domains),
|
top_queried_domains: normalizeTopStats(stats.top_queried_domains),
|
||||||
avg_processing_time: secondsToMilliseconds(stats.avg_processing_time),
|
avg_processing_time: secondsToMilliseconds(stats.avg_processing_time),
|
||||||
};
|
};
|
||||||
|
@ -28,19 +28,17 @@ const countCell = dnsQueries =>
|
|||||||
return <Cell value={value} percent={percent} color={percentColor} />;
|
return <Cell value={value} percent={percent} color={percentColor} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const clientCell = (clients, autoClients, t) =>
|
const clientCell = t =>
|
||||||
function cell(row) {
|
function cell(row) {
|
||||||
const { value } = row;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="logs__row logs__row--overflow logs__row--column">
|
<div className="logs__row logs__row--overflow logs__row--column">
|
||||||
{formatClientCell(value, clients, autoClients, t)}
|
{formatClientCell(row, t)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Clients = ({
|
const Clients = ({
|
||||||
t, refreshButton, topClients, subtitle, clients, autoClients, dnsQueries,
|
t, refreshButton, topClients, subtitle, dnsQueries,
|
||||||
}) => (
|
}) => (
|
||||||
<Card
|
<Card
|
||||||
title={t('top_clients')}
|
title={t('top_clients')}
|
||||||
@ -49,9 +47,10 @@ const Clients = ({
|
|||||||
refresh={refreshButton}
|
refresh={refreshButton}
|
||||||
>
|
>
|
||||||
<ReactTable
|
<ReactTable
|
||||||
data={topClients.map(({ name: ip, count }) => ({
|
data={topClients.map(({ name: ip, count, info }) => ({
|
||||||
ip,
|
ip,
|
||||||
count,
|
count,
|
||||||
|
info,
|
||||||
}))}
|
}))}
|
||||||
columns={[
|
columns={[
|
||||||
{
|
{
|
||||||
@ -59,7 +58,7 @@ const Clients = ({
|
|||||||
accessor: 'ip',
|
accessor: 'ip',
|
||||||
sortMethod: (a, b) =>
|
sortMethod: (a, b) =>
|
||||||
parseInt(a.replace(/\./g, ''), 10) - parseInt(b.replace(/\./g, ''), 10),
|
parseInt(a.replace(/\./g, ''), 10) - parseInt(b.replace(/\./g, ''), 10),
|
||||||
Cell: clientCell(clients, autoClients, t),
|
Cell: clientCell(t),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: <Trans>requests_count</Trans>,
|
Header: <Trans>requests_count</Trans>,
|
||||||
|
@ -20,7 +20,6 @@ class Dashboard extends Component {
|
|||||||
getAllStats = () => {
|
getAllStats = () => {
|
||||||
this.props.getStats();
|
this.props.getStats();
|
||||||
this.props.getStatsConfig();
|
this.props.getStatsConfig();
|
||||||
this.props.getClients();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
getToggleFilteringButton = () => {
|
getToggleFilteringButton = () => {
|
||||||
@ -44,7 +43,6 @@ class Dashboard extends Component {
|
|||||||
const { dashboard, stats, t } = this.props;
|
const { dashboard, stats, t } = this.props;
|
||||||
const dashboardProcessing =
|
const dashboardProcessing =
|
||||||
dashboard.processing ||
|
dashboard.processing ||
|
||||||
dashboard.processingClients ||
|
|
||||||
stats.processingStats ||
|
stats.processingStats ||
|
||||||
stats.processingGetConfig;
|
stats.processingGetConfig;
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@ class Logs extends Component {
|
|||||||
this.props.setLogsPage(TABLE_FIRST_PAGE);
|
this.props.setLogsPage(TABLE_FIRST_PAGE);
|
||||||
this.getLogs(...INITIAL_REQUEST_DATA);
|
this.getLogs(...INITIAL_REQUEST_DATA);
|
||||||
this.props.getFilteringStatus();
|
this.props.getFilteringStatus();
|
||||||
this.props.getClients();
|
|
||||||
this.props.getLogsConfig();
|
this.props.getLogsConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,9 +190,9 @@ class Logs extends Component {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getClientCell = ({ original, value }) => {
|
getClientCell = (row) => {
|
||||||
const { dashboard, t } = this.props;
|
const { original } = row;
|
||||||
const { clients, autoClients } = dashboard;
|
const { t } = this.props;
|
||||||
const { reason, domain } = original;
|
const { reason, domain } = original;
|
||||||
const isFiltered = this.checkFiltered(reason);
|
const isFiltered = this.checkFiltered(reason);
|
||||||
const isRewrite = this.checkRewrite(reason);
|
const isRewrite = this.checkRewrite(reason);
|
||||||
@ -201,7 +200,7 @@ class Logs extends Component {
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div className="logs__row logs__row--overflow logs__row--column">
|
<div className="logs__row logs__row--overflow logs__row--column">
|
||||||
{formatClientCell(value, clients, autoClients, t)}
|
{formatClientCell(row, t)}
|
||||||
</div>
|
</div>
|
||||||
{isRewrite ? (
|
{isRewrite ? (
|
||||||
<div className="logs__action">
|
<div className="logs__action">
|
||||||
@ -232,12 +231,11 @@ class Logs extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderLogs() {
|
renderLogs() {
|
||||||
const { queryLogs, dashboard, t } = this.props;
|
const { queryLogs, t } = this.props;
|
||||||
const { processingClients } = dashboard;
|
|
||||||
const {
|
const {
|
||||||
processingGetLogs, processingGetConfig, logs, pages, page,
|
processingGetLogs, processingGetConfig, logs, pages, page,
|
||||||
} = queryLogs;
|
} = queryLogs;
|
||||||
const isLoading = processingGetLogs || processingClients || processingGetConfig;
|
const isLoading = processingGetLogs || processingGetConfig;
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import { getClientInfo, getAutoClientInfo, normalizeWhois } from './helpers';
|
import { normalizeWhois } from './helpers';
|
||||||
import { WHOIS_ICONS } from './constants';
|
import { WHOIS_ICONS } from './constants';
|
||||||
|
|
||||||
const getFormattedWhois = (whois, t) => {
|
const getFormattedWhois = (whois, t) => {
|
||||||
@ -22,26 +22,29 @@ const getFormattedWhois = (whois, t) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const formatClientCell = (value, clients, autoClients, t) => {
|
export const formatClientCell = (row, t) => {
|
||||||
const clientInfo = getClientInfo(clients, value) || getAutoClientInfo(autoClients, value);
|
const { value, original: { info } } = row;
|
||||||
const { name, whois } = clientInfo;
|
|
||||||
let whoisContainer = '';
|
let whoisContainer = '';
|
||||||
let nameContainer = value;
|
let nameContainer = value;
|
||||||
|
|
||||||
if (name) {
|
if (info) {
|
||||||
nameContainer = (
|
const { name, whois } = info;
|
||||||
<span className="logs__text logs__text--wrap" title={`${name} (${value})`}>
|
|
||||||
{name} <small>({value})</small>
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (whois) {
|
if (name) {
|
||||||
whoisContainer = (
|
nameContainer = (
|
||||||
<div className="logs__text logs__text--wrap logs__text--whois">
|
<span className="logs__text logs__text--wrap" title={`${name} (${value})`}>
|
||||||
{getFormattedWhois(whois, t)}
|
{name} <small>({value})</small>
|
||||||
</div>
|
</span>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (whois) {
|
||||||
|
whoisContainer = (
|
||||||
|
<div className="logs__text logs__text--wrap logs__text--whois">
|
||||||
|
{getFormattedWhois(whois, t)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -8,6 +8,7 @@ import subDays from 'date-fns/sub_days';
|
|||||||
import round from 'lodash/round';
|
import round from 'lodash/round';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import i18n from 'i18next';
|
import i18n from 'i18next';
|
||||||
|
import uniqBy from 'lodash/uniqBy';
|
||||||
import versionCompare from './versionCompare';
|
import versionCompare from './versionCompare';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -92,6 +93,17 @@ export const normalizeTopStats = stats => (
|
|||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const addClientInfo = (data, clients, param) => (
|
||||||
|
data.map((row) => {
|
||||||
|
const clientIp = row[param];
|
||||||
|
const info = clients.find(item => item[clientIp]) || '';
|
||||||
|
return {
|
||||||
|
...row,
|
||||||
|
info: (info && info[clientIp]) || '',
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
export const normalizeFilteringStatus = (filteringStatus) => {
|
export const normalizeFilteringStatus = (filteringStatus) => {
|
||||||
const {
|
const {
|
||||||
enabled, filters, user_rules: userRules, interval,
|
enabled, filters, user_rules: userRules, interval,
|
||||||
@ -342,3 +354,13 @@ export const getPathWithQueryString = (path, params) => {
|
|||||||
|
|
||||||
return `${path}?${searchParams.toString()}`;
|
return `${path}?${searchParams.toString()}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getParamsForClientsSearch = (data, param) => {
|
||||||
|
const uniqueClients = uniqBy(data, param);
|
||||||
|
return uniqueClients
|
||||||
|
.reduce((acc, item, idx) => {
|
||||||
|
const key = `ip${idx}`;
|
||||||
|
acc[key] = item[param];
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user