mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-12-16 11:52:58 +03:00
+ client: separate filters from the table component
This commit is contained in:
parent
6b64d393bd
commit
e243e69a6e
@ -4,8 +4,19 @@ import apiClient from '../api/Api';
|
|||||||
import { addErrorToast, addSuccessToast } from './index';
|
import { addErrorToast, addSuccessToast } from './index';
|
||||||
import { normalizeLogs } from '../helpers/helpers';
|
import { normalizeLogs } from '../helpers/helpers';
|
||||||
|
|
||||||
|
const getLogsWithParams = async (config) => {
|
||||||
|
const { older_than, filter, ...values } = config;
|
||||||
|
const rawLogs = await apiClient.getQueryLog({ ...filter, older_than });
|
||||||
|
const { data, oldest } = rawLogs;
|
||||||
|
const logs = normalizeLogs(data);
|
||||||
|
|
||||||
|
return {
|
||||||
|
logs, oldest, older_than, filter, ...values,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const setLogsPagination = createAction('LOGS_PAGINATION');
|
export const setLogsPagination = createAction('LOGS_PAGINATION');
|
||||||
export const setLogsFilter = createAction('LOGS_FILTER');
|
export const setLogsPage = createAction('SET_LOG_PAGE');
|
||||||
|
|
||||||
export const getLogsRequest = createAction('GET_LOGS_REQUEST');
|
export const getLogsRequest = createAction('GET_LOGS_REQUEST');
|
||||||
export const getLogsFailure = createAction('GET_LOGS_FAILURE');
|
export const getLogsFailure = createAction('GET_LOGS_FAILURE');
|
||||||
@ -14,19 +25,30 @@ export const getLogsSuccess = createAction('GET_LOGS_SUCCESS');
|
|||||||
export const getLogs = config => async (dispatch) => {
|
export const getLogs = config => async (dispatch) => {
|
||||||
dispatch(getLogsRequest());
|
dispatch(getLogsRequest());
|
||||||
try {
|
try {
|
||||||
const { filter, older_than } = config;
|
const logs = await getLogsWithParams(config);
|
||||||
const rawLogs = await apiClient.getQueryLog({ ...filter, older_than });
|
dispatch(getLogsSuccess(logs));
|
||||||
const { data, oldest } = rawLogs;
|
|
||||||
const logs = normalizeLogs(data);
|
|
||||||
dispatch(getLogsSuccess({
|
|
||||||
logs, oldest, filter, ...config,
|
|
||||||
}));
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(addErrorToast({ error }));
|
dispatch(addErrorToast({ error }));
|
||||||
dispatch(getLogsFailure(error));
|
dispatch(getLogsFailure(error));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const setLogsFilterRequest = createAction('SET_LOGS_FILTER_REQUEST');
|
||||||
|
export const setLogsFilterFailure = createAction('SET_LOGS_FILTER_FAILURE');
|
||||||
|
export const setLogsFilterSuccess = createAction('SET_LOGS_FILTER_SUCCESS');
|
||||||
|
|
||||||
|
export const setLogsFilter = filter => async (dispatch) => {
|
||||||
|
dispatch(setLogsFilterRequest());
|
||||||
|
try {
|
||||||
|
const logs = await getLogsWithParams({ older_than: '', filter });
|
||||||
|
dispatch(setLogsFilterSuccess(logs));
|
||||||
|
dispatch(setLogsPage(0));
|
||||||
|
} catch (error) {
|
||||||
|
dispatch(addErrorToast({ error }));
|
||||||
|
dispatch(setLogsFilterFailure(error));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const clearLogsRequest = createAction('CLEAR_LOGS_REQUEST');
|
export const clearLogsRequest = createAction('CLEAR_LOGS_REQUEST');
|
||||||
export const clearLogsFailure = createAction('CLEAR_LOGS_FAILURE');
|
export const clearLogsFailure = createAction('CLEAR_LOGS_FAILURE');
|
||||||
export const clearLogsSuccess = createAction('CLEAR_LOGS_SUCCESS');
|
export const clearLogsSuccess = createAction('CLEAR_LOGS_SUCCESS');
|
||||||
|
116
client/src/components/Logs/Filters/Form.js
Normal file
116
client/src/components/Logs/Filters/Form.js
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import React, { Fragment } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Field, reduxForm } from 'redux-form';
|
||||||
|
import { withNamespaces, Trans } from 'react-i18next';
|
||||||
|
import flow from 'lodash/flow';
|
||||||
|
|
||||||
|
import { renderField } from '../../../helpers/form';
|
||||||
|
import { RESPONSE_FILTER } from '../../../helpers/constants';
|
||||||
|
import Tooltip from '../../ui/Tooltip';
|
||||||
|
|
||||||
|
const renderFilterField = ({
|
||||||
|
input,
|
||||||
|
id,
|
||||||
|
className,
|
||||||
|
placeholder,
|
||||||
|
type,
|
||||||
|
disabled,
|
||||||
|
autoComplete,
|
||||||
|
tooltip,
|
||||||
|
meta: { touched, error },
|
||||||
|
}) => (
|
||||||
|
<Fragment>
|
||||||
|
<div className="logs__input-wrap">
|
||||||
|
<input
|
||||||
|
{...input}
|
||||||
|
id={id}
|
||||||
|
placeholder={placeholder}
|
||||||
|
type={type}
|
||||||
|
className={className}
|
||||||
|
disabled={disabled}
|
||||||
|
autoComplete={autoComplete}
|
||||||
|
/>
|
||||||
|
<span className="logs__notice">
|
||||||
|
<Tooltip text={tooltip} type='tooltip-custom--logs' />
|
||||||
|
</span>
|
||||||
|
{!disabled &&
|
||||||
|
touched &&
|
||||||
|
(error && <span className="form__message form__message--error">{error}</span>)}
|
||||||
|
</div>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
|
||||||
|
const Form = (props) => {
|
||||||
|
const {
|
||||||
|
t,
|
||||||
|
handleChange,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleChange}>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-3">
|
||||||
|
<Field
|
||||||
|
id="domain"
|
||||||
|
name="domain"
|
||||||
|
component={renderFilterField}
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
placeholder={t('domain_name_table_header')}
|
||||||
|
tooltip={t('query_log_strict_search')}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-3">
|
||||||
|
<Field
|
||||||
|
id="type"
|
||||||
|
name="type"
|
||||||
|
component={renderField}
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
placeholder={t('type_table_header')}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-3">
|
||||||
|
<Field
|
||||||
|
name="response"
|
||||||
|
component="select"
|
||||||
|
className="form-control custom-select"
|
||||||
|
>
|
||||||
|
<option value={RESPONSE_FILTER.ALL}>
|
||||||
|
<Trans>show_all_filter_type</Trans>
|
||||||
|
</option>
|
||||||
|
<option value={RESPONSE_FILTER.FILTERED}>
|
||||||
|
<Trans>show_filtered_type</Trans>
|
||||||
|
</option>
|
||||||
|
</Field>
|
||||||
|
</div>
|
||||||
|
<div className="col-3">
|
||||||
|
<Field
|
||||||
|
id="client"
|
||||||
|
name="client"
|
||||||
|
component={renderFilterField}
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
placeholder={t('client_table_header')}
|
||||||
|
tooltip={t('query_log_strict_search')}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Form.propTypes = {
|
||||||
|
handleChange: PropTypes.func,
|
||||||
|
t: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default flow([
|
||||||
|
withNamespaces(),
|
||||||
|
reduxForm({
|
||||||
|
form: 'logsFilterForm',
|
||||||
|
}),
|
||||||
|
])(Form);
|
45
client/src/components/Logs/Filters/index.js
Normal file
45
client/src/components/Logs/Filters/index.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import debounce from 'lodash/debounce';
|
||||||
|
|
||||||
|
import { DEBOUNCE_FILTER_TIMEOUT, RESPONSE_FILTER } from '../../../helpers/constants';
|
||||||
|
import { isValidQuestionType } from '../../../helpers/helpers';
|
||||||
|
import Form from './Form';
|
||||||
|
|
||||||
|
class Filters extends Component {
|
||||||
|
getFilters = (filtered) => {
|
||||||
|
const {
|
||||||
|
domain, client, type, response,
|
||||||
|
} = filtered;
|
||||||
|
|
||||||
|
return {
|
||||||
|
filter_domain: domain || '',
|
||||||
|
filter_client: client || '',
|
||||||
|
filter_question_type: isValidQuestionType(type) ? type.toUpperCase() : '',
|
||||||
|
filter_response_status: response === RESPONSE_FILTER.FILTERED ? response : '',
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
handleFormChange = debounce((values) => {
|
||||||
|
const filter = this.getFilters(values);
|
||||||
|
this.props.setLogsFilter(filter);
|
||||||
|
}, DEBOUNCE_FILTER_TIMEOUT);
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { filter } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form
|
||||||
|
initialValues={filter}
|
||||||
|
onChange={this.handleFormChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Filters.propTypes = {
|
||||||
|
filter: PropTypes.object.isRequired,
|
||||||
|
setLogsFilter: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Filters;
|
@ -5,46 +5,40 @@ import escapeRegExp from 'lodash/escapeRegExp';
|
|||||||
import endsWith from 'lodash/endsWith';
|
import endsWith from 'lodash/endsWith';
|
||||||
import { Trans, withNamespaces } from 'react-i18next';
|
import { Trans, withNamespaces } from 'react-i18next';
|
||||||
import { HashLink as Link } from 'react-router-hash-link';
|
import { HashLink as Link } from 'react-router-hash-link';
|
||||||
import debounce from 'lodash/debounce';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
formatTime,
|
formatTime,
|
||||||
formatDateTime,
|
formatDateTime,
|
||||||
isValidQuestionType,
|
|
||||||
} from '../../helpers/helpers';
|
} from '../../helpers/helpers';
|
||||||
import { SERVICES, FILTERED_STATUS, DEBOUNCE_TIMEOUT, DEFAULT_LOGS_FILTER } from '../../helpers/constants';
|
import { SERVICES, FILTERED_STATUS, DEFAULT_LOGS_FILTER, RESPONSE_FILTER, TABLE_DEFAULT_PAGE_SIZE } from '../../helpers/constants';
|
||||||
import { getTrackerData } from '../../helpers/trackers/trackers';
|
import { getTrackerData } from '../../helpers/trackers/trackers';
|
||||||
import { formatClientCell } from '../../helpers/formatClientCell';
|
import { formatClientCell } from '../../helpers/formatClientCell';
|
||||||
|
|
||||||
|
import Filters from './Filters';
|
||||||
import PageTitle from '../ui/PageTitle';
|
import PageTitle from '../ui/PageTitle';
|
||||||
import Card from '../ui/Card';
|
import Card from '../ui/Card';
|
||||||
import Loading from '../ui/Loading';
|
import Loading from '../ui/Loading';
|
||||||
import PopoverFiltered from '../ui/PopoverFilter';
|
import PopoverFiltered from '../ui/PopoverFilter';
|
||||||
import Popover from '../ui/Popover';
|
import Popover from '../ui/Popover';
|
||||||
import Tooltip from '../ui/Tooltip';
|
|
||||||
import './Logs.css';
|
import './Logs.css';
|
||||||
|
|
||||||
const TABLE_FIRST_PAGE = 0;
|
const TABLE_FIRST_PAGE = 0;
|
||||||
const TABLE_DEFAULT_PAGE_SIZE = 100;
|
|
||||||
const INITIAL_REQUEST_DATA = ['', DEFAULT_LOGS_FILTER, TABLE_FIRST_PAGE, TABLE_DEFAULT_PAGE_SIZE];
|
const INITIAL_REQUEST_DATA = ['', DEFAULT_LOGS_FILTER, TABLE_FIRST_PAGE, TABLE_DEFAULT_PAGE_SIZE];
|
||||||
const FILTERED_REASON = 'Filtered';
|
const FILTERED_REASON = 'Filtered';
|
||||||
const RESPONSE_FILTER = {
|
|
||||||
ALL: 'all',
|
|
||||||
FILTERED: 'filtered',
|
|
||||||
};
|
|
||||||
|
|
||||||
class Logs extends Component {
|
class Logs extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
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.getClients();
|
||||||
this.props.getLogsConfig();
|
this.props.getLogsConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
getLogs = (older_than, filter, page, pageSize, filtered) => {
|
getLogs = (older_than, filter, page) => {
|
||||||
if (this.props.queryLogs.enabled) {
|
if (this.props.queryLogs.enabled) {
|
||||||
this.props.getLogs({
|
this.props.getLogs({
|
||||||
older_than, filter, page, pageSize, filtered,
|
older_than, filter, page, pageSize: TABLE_DEFAULT_PAGE_SIZE,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -53,16 +47,6 @@ class Logs extends Component {
|
|||||||
window.location.reload();
|
window.location.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
handleLogsFiltering = debounce((older_than, filter, page, pageSize, filtered) => {
|
|
||||||
this.props.getLogs({
|
|
||||||
older_than,
|
|
||||||
filter,
|
|
||||||
page,
|
|
||||||
pageSize,
|
|
||||||
filtered,
|
|
||||||
});
|
|
||||||
}, DEBOUNCE_TIMEOUT);
|
|
||||||
|
|
||||||
renderTooltip = (isFiltered, rule, filter, service) =>
|
renderTooltip = (isFiltered, rule, filter, service) =>
|
||||||
isFiltered && <PopoverFiltered rule={rule} filter={filter} service={service} />;
|
isFiltered && <PopoverFiltered rule={rule} filter={filter} service={service} />;
|
||||||
|
|
||||||
@ -232,70 +216,25 @@ class Logs extends Component {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getFilterInput = ({ filter, onChange }) => (
|
|
||||||
<Fragment>
|
|
||||||
<div className="logs__input-wrap">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
onChange={event => onChange(event.target.value)}
|
|
||||||
value={filter ? filter.value : ''}
|
|
||||||
/>
|
|
||||||
<span className="logs__notice">
|
|
||||||
<Tooltip text={this.props.t('query_log_strict_search')} type='tooltip-custom--logs' />
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
|
|
||||||
getFilters = (filtered) => {
|
|
||||||
const filteredObj = filtered.reduce((acc, cur) => ({ ...acc, [cur.id]: cur.value }), {});
|
|
||||||
const {
|
|
||||||
domain, client, type, response,
|
|
||||||
} = filteredObj;
|
|
||||||
|
|
||||||
return {
|
|
||||||
filter_domain: domain || '',
|
|
||||||
filter_client: client || '',
|
|
||||||
filter_question_type: isValidQuestionType(type) ? type.toUpperCase() : '',
|
|
||||||
filter_response_status: response === RESPONSE_FILTER.FILTERED ? response : '',
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchData = (state) => {
|
fetchData = (state) => {
|
||||||
const { pageSize, page, pages } = state;
|
const { pages } = state;
|
||||||
const { filter, oldest } = this.props.queryLogs;
|
const {
|
||||||
|
filter, oldest, page,
|
||||||
|
} = this.props.queryLogs;
|
||||||
const isLastPage = pages && (page + 1 === pages);
|
const isLastPage = pages && (page + 1 === pages);
|
||||||
|
|
||||||
if (isLastPage) {
|
if (isLastPage) {
|
||||||
this.getLogs(oldest, filter, page, pageSize, false);
|
this.getLogs(oldest, filter, page);
|
||||||
} else {
|
} else {
|
||||||
this.props.setLogsPagination({ page, pageSize });
|
this.props.setLogsPagination({ page, pageSize: TABLE_DEFAULT_PAGE_SIZE });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleFilterChange = (filtered) => {
|
|
||||||
const filters = this.getFilters(filtered);
|
|
||||||
this.props.setLogsFilter(filters);
|
|
||||||
this.handleLogsFiltering('', filters, TABLE_FIRST_PAGE, TABLE_DEFAULT_PAGE_SIZE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
showTotalPagesCount = (pages) => {
|
|
||||||
const { total, isEntireLog } = this.props.queryLogs;
|
|
||||||
const showEllipsis = !isEntireLog && total >= 500;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<span className="-totalPages">
|
|
||||||
{pages || 1}{showEllipsis && '…' }
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderLogs() {
|
renderLogs() {
|
||||||
const { queryLogs, dashboard, t } = this.props;
|
const { queryLogs, dashboard, t } = this.props;
|
||||||
const { processingClients } = dashboard;
|
const { processingClients } = dashboard;
|
||||||
const {
|
const {
|
||||||
processingGetLogs, processingGetConfig, logs, pages,
|
processingGetLogs, processingGetConfig, logs, pages, page,
|
||||||
} = queryLogs;
|
} = queryLogs;
|
||||||
const isLoading = processingGetLogs || processingClients || processingGetConfig;
|
const isLoading = processingGetLogs || processingClients || processingGetConfig;
|
||||||
|
|
||||||
@ -304,7 +243,6 @@ class Logs extends Component {
|
|||||||
Header: t('time_table_header'),
|
Header: t('time_table_header'),
|
||||||
accessor: 'time',
|
accessor: 'time',
|
||||||
maxWidth: 100,
|
maxWidth: 100,
|
||||||
filterable: false,
|
|
||||||
Cell: this.getTimeCell,
|
Cell: this.getTimeCell,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -360,18 +298,20 @@ class Logs extends Component {
|
|||||||
return (
|
return (
|
||||||
<ReactTable
|
<ReactTable
|
||||||
manual
|
manual
|
||||||
filterable
|
|
||||||
minRows={5}
|
minRows={5}
|
||||||
|
page={page}
|
||||||
pages={pages}
|
pages={pages}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
filterable={false}
|
||||||
sortable={false}
|
sortable={false}
|
||||||
data={logs || []}
|
data={logs || []}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
showPagination={true}
|
showPagination={true}
|
||||||
|
showPaginationTop={true}
|
||||||
showPageJump={false}
|
showPageJump={false}
|
||||||
showPageSizeOptions={false}
|
showPageSizeOptions={false}
|
||||||
onFetchData={this.fetchData}
|
onFetchData={this.fetchData}
|
||||||
onFilteredChange={this.handleFilterChange}
|
onPageChange={newPage => this.props.setLogsPage(newPage)}
|
||||||
className="logs__table"
|
className="logs__table"
|
||||||
defaultPageSize={TABLE_DEFAULT_PAGE_SIZE}
|
defaultPageSize={TABLE_DEFAULT_PAGE_SIZE}
|
||||||
previousText={t('previous_btn')}
|
previousText={t('previous_btn')}
|
||||||
@ -381,7 +321,6 @@ class Logs extends Component {
|
|||||||
noDataText={t('no_logs_found')}
|
noDataText={t('no_logs_found')}
|
||||||
pageText={''}
|
pageText={''}
|
||||||
ofText={''}
|
ofText={''}
|
||||||
renderCurrentPage={() => false}
|
|
||||||
renderTotalPagesCount={() => false}
|
renderTotalPagesCount={() => false}
|
||||||
defaultFilterMethod={(filter, row) => {
|
defaultFilterMethod={(filter, row) => {
|
||||||
const id = filter.pivotId || filter.id;
|
const id = filter.pivotId || filter.id;
|
||||||
@ -446,7 +385,17 @@ class Logs extends Component {
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
<PageTitle title={t('query_log')}>{refreshButton}</PageTitle>
|
<PageTitle title={t('query_log')}>{refreshButton}</PageTitle>
|
||||||
{enabled && processingGetConfig && <Loading />}
|
{enabled && processingGetConfig && <Loading />}
|
||||||
{enabled && !processingGetConfig && <Card>{this.renderLogs()}</Card>}
|
{enabled && !processingGetConfig && (
|
||||||
|
<Fragment>
|
||||||
|
<Card>
|
||||||
|
<Filters
|
||||||
|
filter={queryLogs.filter}
|
||||||
|
setLogsFilter={this.props.setLogsFilter}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
<Card>{this.renderLogs()}</Card>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
{!enabled && !processingGetConfig && (
|
{!enabled && !processingGetConfig && (
|
||||||
<Card>
|
<Card>
|
||||||
<div className="lead text-center py-6">
|
<div className="lead text-center py-6">
|
||||||
@ -479,6 +428,7 @@ Logs.propTypes = {
|
|||||||
getLogsConfig: PropTypes.func.isRequired,
|
getLogsConfig: PropTypes.func.isRequired,
|
||||||
setLogsPagination: PropTypes.func.isRequired,
|
setLogsPagination: PropTypes.func.isRequired,
|
||||||
setLogsFilter: PropTypes.func.isRequired,
|
setLogsFilter: PropTypes.func.isRequired,
|
||||||
|
setLogsPage: PropTypes.func.isRequired,
|
||||||
t: PropTypes.func.isRequired,
|
t: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
top: calc(100% + 10px);
|
top: calc(100% + 10px);
|
||||||
right: -10px;
|
right: -10px;
|
||||||
left: initial;
|
left: initial;
|
||||||
|
width: 255px;
|
||||||
transform: none;
|
transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { addSuccessToast, getClients } from '../actions';
|
import { addSuccessToast, getClients } from '../actions';
|
||||||
import { getFilteringStatus, setRules } from '../actions/filtering';
|
import { getFilteringStatus, setRules } from '../actions/filtering';
|
||||||
import { getLogs, getLogsConfig, setLogsPagination, setLogsFilter } from '../actions/queryLogs';
|
import { getLogs, getLogsConfig, setLogsPagination, setLogsFilter, setLogsPage } from '../actions/queryLogs';
|
||||||
import Logs from '../components/Logs';
|
import Logs from '../components/Logs';
|
||||||
|
|
||||||
const mapStateToProps = (state) => {
|
const mapStateToProps = (state) => {
|
||||||
@ -19,6 +19,7 @@ const mapDispatchToProps = {
|
|||||||
getLogsConfig,
|
getLogsConfig,
|
||||||
setLogsPagination,
|
setLogsPagination,
|
||||||
setLogsFilter,
|
setLogsFilter,
|
||||||
|
setLogsPage,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
@ -141,6 +141,7 @@ export const STANDARD_HTTPS_PORT = 443;
|
|||||||
export const EMPTY_DATE = '0001-01-01T00:00:00Z';
|
export const EMPTY_DATE = '0001-01-01T00:00:00Z';
|
||||||
|
|
||||||
export const DEBOUNCE_TIMEOUT = 300;
|
export const DEBOUNCE_TIMEOUT = 300;
|
||||||
|
export const DEBOUNCE_FILTER_TIMEOUT = 500;
|
||||||
export const CHECK_TIMEOUT = 1000;
|
export const CHECK_TIMEOUT = 1000;
|
||||||
export const STOP_TIMEOUT = 10000;
|
export const STOP_TIMEOUT = 10000;
|
||||||
|
|
||||||
@ -379,3 +380,9 @@ export const DEFAULT_LOGS_FILTER = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const DEFAULT_LANGUAGE = 'en';
|
export const DEFAULT_LANGUAGE = 'en';
|
||||||
|
|
||||||
|
export const TABLE_DEFAULT_PAGE_SIZE = 100;
|
||||||
|
export const RESPONSE_FILTER = {
|
||||||
|
ALL: 'all',
|
||||||
|
FILTERED: 'filtered',
|
||||||
|
};
|
||||||
|
@ -20,15 +20,43 @@ const queryLogs = handleActions(
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
[actions.setLogsFilter]: (state, { payload }) => (
|
[actions.setLogsPage]: (state, { payload }) => ({
|
||||||
{ ...state, filter: payload }
|
...state,
|
||||||
),
|
page: payload,
|
||||||
|
}),
|
||||||
|
|
||||||
|
[actions.setLogsFilterRequest]: state => ({ ...state, processingGetLogs: true }),
|
||||||
|
[actions.setLogsFilterFailure]: state => ({ ...state, processingGetLogs: false }),
|
||||||
|
[actions.setLogsFilterSuccess]: (state, { payload }) => {
|
||||||
|
const { logs, oldest, filter } = payload;
|
||||||
|
const pageSize = 100;
|
||||||
|
const page = 0;
|
||||||
|
|
||||||
|
const pages = Math.ceil(logs.length / pageSize);
|
||||||
|
const total = logs.length;
|
||||||
|
const rowsStart = pageSize * page;
|
||||||
|
const rowsEnd = (pageSize * page) + pageSize;
|
||||||
|
const logsSlice = logs.slice(rowsStart, rowsEnd);
|
||||||
|
const isFiltered = Object.keys(filter).some(key => filter[key]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
oldest,
|
||||||
|
filter,
|
||||||
|
isFiltered,
|
||||||
|
pages,
|
||||||
|
total,
|
||||||
|
logs: logsSlice,
|
||||||
|
allLogs: logs,
|
||||||
|
processingGetLogs: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
[actions.getLogsRequest]: state => ({ ...state, processingGetLogs: true }),
|
[actions.getLogsRequest]: state => ({ ...state, processingGetLogs: true }),
|
||||||
[actions.getLogsFailure]: state => ({ ...state, processingGetLogs: false }),
|
[actions.getLogsFailure]: state => ({ ...state, processingGetLogs: false }),
|
||||||
[actions.getLogsSuccess]: (state, { payload }) => {
|
[actions.getLogsSuccess]: (state, { payload }) => {
|
||||||
const {
|
const {
|
||||||
logs, oldest, older_than, page, pageSize, filtered,
|
logs, oldest, older_than, page, pageSize,
|
||||||
} = payload;
|
} = payload;
|
||||||
let logsWithOffset = state.allLogs.length > 0 ? state.allLogs : logs;
|
let logsWithOffset = state.allLogs.length > 0 ? state.allLogs : logs;
|
||||||
let allLogs = logs;
|
let allLogs = logs;
|
||||||
@ -36,9 +64,6 @@ const queryLogs = handleActions(
|
|||||||
if (older_than) {
|
if (older_than) {
|
||||||
logsWithOffset = [...state.allLogs, ...logs];
|
logsWithOffset = [...state.allLogs, ...logs];
|
||||||
allLogs = [...state.allLogs, ...logs];
|
allLogs = [...state.allLogs, ...logs];
|
||||||
} else if (filtered) {
|
|
||||||
logsWithOffset = logs;
|
|
||||||
allLogs = logs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const pages = Math.ceil(logsWithOffset.length / pageSize);
|
const pages = Math.ceil(logsWithOffset.length / pageSize);
|
||||||
@ -91,11 +116,13 @@ const queryLogs = handleActions(
|
|||||||
logs: [],
|
logs: [],
|
||||||
interval: 1,
|
interval: 1,
|
||||||
allLogs: [],
|
allLogs: [],
|
||||||
|
page: 0,
|
||||||
pages: 0,
|
pages: 0,
|
||||||
total: 0,
|
total: 0,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
oldest: '',
|
oldest: '',
|
||||||
filter: DEFAULT_LOGS_FILTER,
|
filter: DEFAULT_LOGS_FILTER,
|
||||||
|
isFiltered: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user