Skip to content

Commit

Permalink
ADG-8179 add persistent client from query log context menu
Browse files Browse the repository at this point in the history
  • Loading branch information
IldarKamalov committed Feb 5, 2024
1 parent 60a978c commit 14a7190
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ NOTE: Add new changes BELOW THIS COMMENT.

### Added

- Context menu item in the Query Log to add a Client to the Persistent client list
- Etc timezones to the timezone list ([#6568]).
- The schema version of the configuration file to the output of running
`AdGuardHome` (or `AdGuardHome.exe`) with `-v --version` command-line options
Expand Down
2 changes: 2 additions & 0 deletions client/src/__locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@
"allow_this_client": "Allow this client",
"block_for_this_client_only": "Block for this client only",
"unblock_for_this_client_only": "Unblock for this client only",
"add_persistent_client": "Add as persistent client",
"time_table_header": "Time",
"date": "Date",
"domain_name_table_header": "Domain name",
Expand Down Expand Up @@ -465,6 +466,7 @@
"form_add_id": "Add identifier",
"form_client_name": "Enter client name",
"name": "Name",
"client_name": "Client {{id}}",
"client_global_settings": "Use global settings",
"client_deleted": "Client \"{{key}}\" successfully deleted",
"client_added": "Client \"{{key}}\" successfully added",
Expand Down
2 changes: 2 additions & 0 deletions client/src/components/Filters/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ ReactModal.setAppElement('#root');
const MODAL_TYPE_TO_TITLE_TYPE_MAP = {
[MODAL_TYPE.EDIT_FILTERS]: 'edit',
[MODAL_TYPE.ADD_FILTERS]: 'new',
[MODAL_TYPE.EDIT_CLIENT]: 'edit',
[MODAL_TYPE.ADD_CLIENT]: 'new',
[MODAL_TYPE.SELECT_MODAL_TYPE]: 'new',
[MODAL_TYPE.CHOOSE_FILTERING_LIST]: 'choose',
};
Expand Down
16 changes: 14 additions & 2 deletions client/src/components/Logs/Cells/ClientCell.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { nanoid } from 'nanoid';
import classNames from 'classnames';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { Link, useHistory } from 'react-router-dom';
import propTypes from 'prop-types';

import { checkFiltered, getBlockingClientName } from '../../../helpers/helpers';
Expand All @@ -25,12 +25,14 @@ const ClientCell = ({
}) => {
const { t } = useTranslation();
const dispatch = useDispatch();
const history = useHistory();
const autoClients = useSelector((state) => state.dashboard.autoClients, shallowEqual);
const isDetailed = useSelector((state) => state.queryLogs.isDetailed);
const allowedСlients = useSelector((state) => state.access.allowed_clients, shallowEqual);
const [isOptionsOpened, setOptionsOpened] = useState(false);

const autoClient = autoClients.find((autoClient) => autoClient.name === client);
const clients = useSelector((state) => state.dashboard.clients);
const source = autoClient?.source;
const whoisAvailable = client_info && Object.keys(client_info.whois).length > 0;
const clientName = client_info?.name || client_id;
Expand All @@ -55,6 +57,8 @@ const ClientCell = ({

const isFiltered = checkFiltered(reason);

const clientIds = clients.map((c) => c.ids).flat();

const nameClass = classNames('w-90 o-hidden d-flex flex-column', {
'mt-2': isDetailed && !client_info?.name && !whoisAvailable,
'white-space--nowrap': isDetailed,
Expand All @@ -66,7 +70,6 @@ const ClientCell = ({

const renderBlockingButton = (isFiltered, domain) => {
const buttonType = isFiltered ? BLOCK_ACTIONS.UNBLOCK : BLOCK_ACTIONS.BLOCK;
const clients = useSelector((state) => state.dashboard.clients);

const {
confirmMessage,
Expand Down Expand Up @@ -118,6 +121,15 @@ const ClientCell = ({
},
];

if (!clientIds.includes(client)) {
BUTTON_OPTIONS.push({
name: 'add_persistent_client',
onClick: () => {
history.push(`/#clients?clientId=${client}`);
},
});
}

const getOptions = (options) => {
if (options.length === 0) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { Trans, useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory, useLocation } from 'react-router-dom';
import ReactTable from 'react-table';

import { getAllBlockedServices, getBlockedServices } from '../../../../actions/services';
Expand Down Expand Up @@ -39,15 +40,25 @@ const ClientsTable = ({
}) => {
const [t] = useTranslation();
const dispatch = useDispatch();
const location = useLocation();
const history = useHistory();
const services = useSelector((store) => store?.services);
const globalSettings = useSelector((store) => store?.settings.settingsList) || {};
const params = new URLSearchParams(location.search);
const clientId = params.get('clientId');

const { safesearch } = globalSettings;

useEffect(() => {
dispatch(getAllBlockedServices());
dispatch(getBlockedServices());
dispatch(initSettings());

if (clientId) {
toggleClientModal({
type: MODAL_TYPE.ADD_CLIENT,
});
}
}, []);

const handleFormAdd = (values) => {
Expand Down Expand Up @@ -85,11 +96,15 @@ const ClientsTable = ({
}
}

if (modalType === MODAL_TYPE.EDIT_FILTERS) {
if (modalType === MODAL_TYPE.EDIT_CLIENT) {
handleFormUpdate(config, modalClientName);
} else {
handleFormAdd(config);
}

if (clientId) {
history.push('/#clients');
}
};

const getOptionsWithLabels = (options) => (
Expand Down Expand Up @@ -133,6 +148,17 @@ const ClientsTable = ({
}
};

const handleClose = () => {
toggleClientModal();

const params = new URLSearchParams(location.search);
const clientId = params.get('clientId');

if (clientId) {
history.push('/#clients');
}
};

const columns = [
{
Header: t('table_client'),
Expand Down Expand Up @@ -298,7 +324,7 @@ const ClientsTable = ({
type="button"
className="btn btn-icon btn-outline-primary btn-sm mr-2"
onClick={() => toggleClientModal({
type: MODAL_TYPE.EDIT_FILTERS,
type: MODAL_TYPE.EDIT_CLIENT,
name: clientName,
})
}
Expand Down Expand Up @@ -371,12 +397,13 @@ const ClientsTable = ({
<Modal
isModalOpen={isModalOpen}
modalType={modalType}
toggleClientModal={toggleClientModal}
handleClose={handleClose}
currentClientData={currentClientData}
handleSubmit={handleSubmit}
processingAdding={processingAdding}
processingUpdating={processingUpdating}
tagsOptions={tagsOptions}
clientId={clientId}
/>
</>
</Card>
Expand Down
6 changes: 3 additions & 3 deletions client/src/components/Settings/Clients/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ let Form = (props) => {
useGlobalSettings,
useGlobalServices,
blockedServicesSchedule,
toggleClientModal,
handleClose,
processingAdding,
processingUpdating,
invalid,
Expand Down Expand Up @@ -427,7 +427,7 @@ let Form = (props) => {
disabled={submitting}
onClick={() => {
reset();
toggleClientModal();
handleClose();
}}
>
<Trans>cancel_btn</Trans>
Expand Down Expand Up @@ -456,7 +456,7 @@ Form.propTypes = {
reset: PropTypes.func.isRequired,
change: PropTypes.func.isRequired,
submitting: PropTypes.bool.isRequired,
toggleClientModal: PropTypes.func.isRequired,
handleClose: PropTypes.func.isRequired,
useGlobalSettings: PropTypes.bool,
useGlobalServices: PropTypes.bool,
blockedServicesSchedule: PropTypes.object,
Expand Down
52 changes: 35 additions & 17 deletions client/src/components/Settings/Clients/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import ReactModal from 'react-modal';
import { MODAL_TYPE } from '../../../helpers/constants';
import Form from './Form';

const getInitialData = (initial) => {
const getInitialData = ({
initial, modalType, clientId, clientName,
}) => {
if (initial && initial.blocked_services) {
const { blocked_services } = initial;
const blocked = {};
Expand All @@ -21,46 +23,60 @@ const getInitialData = (initial) => {
};
}

if (modalType !== MODAL_TYPE.EDIT_CLIENT && clientId) {
return {
...initial,
name: clientName,
ids: [clientId],
};
}

return initial;
};

const Modal = (props) => {
const {
isModalOpen,
const Modal = ({
isModalOpen,
modalType,
currentClientData,
handleSubmit,
handleClose,
processingAdding,
processingUpdating,
tagsOptions,
clientId,
t,
}) => {
const initialData = getInitialData({
initial: currentClientData,
modalType,
currentClientData,
handleSubmit,
toggleClientModal,
processingAdding,
processingUpdating,
tagsOptions,
} = props;
const initialData = getInitialData(currentClientData);
clientId,
clientName: t('client_name', { id: clientId }),
});

return (
<ReactModal
className="Modal__Bootstrap modal-dialog modal-dialog-centered modal-dialog--clients"
closeTimeoutMS={0}
isOpen={isModalOpen}
onRequestClose={() => toggleClientModal()}
onRequestClose={handleClose}
>
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title">
{modalType === MODAL_TYPE.EDIT_FILTERS ? (
{modalType === MODAL_TYPE.EDIT_CLIENT ? (
<Trans>client_edit</Trans>
) : (
<Trans>client_new</Trans>
)}
</h4>
<button type="button" className="close" onClick={() => toggleClientModal()}>
<button type="button" className="close" onClick={handleClose}>
<span className="sr-only">Close</span>
</button>
</div>
<Form
initialValues={{ ...initialData }}
onSubmit={handleSubmit}
toggleClientModal={toggleClientModal}
handleClose={handleClose}
processingAdding={processingAdding}
processingUpdating={processingUpdating}
tagsOptions={tagsOptions}
Expand All @@ -75,10 +91,12 @@ Modal.propTypes = {
modalType: PropTypes.string.isRequired,
currentClientData: PropTypes.object.isRequired,
handleSubmit: PropTypes.func.isRequired,
toggleClientModal: PropTypes.func.isRequired,
handleClose: PropTypes.func.isRequired,
processingAdding: PropTypes.bool.isRequired,
processingUpdating: PropTypes.bool.isRequired,
tagsOptions: PropTypes.array.isRequired,
t: PropTypes.func.isRequired,
clientId: PropTypes.string,
};

export default withTranslation()(Modal);
2 changes: 2 additions & 0 deletions client/src/helpers/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ export const MODAL_TYPE = {
EDIT_REWRITE: 'EDIT_REWRITE',
EDIT_LEASE: 'EDIT_LEASE',
ADD_LEASE: 'ADD_LEASE',
ADD_CLIENT: 'ADD_CLIENT',
EDIT_CLIENT: 'EDIT_CLIENT',
};

export const CLIENT_ID = {
Expand Down

0 comments on commit 14a7190

Please sign in to comment.