+ client: handle client tags

This commit is contained in:
Ildar Kamalov
2020-01-28 14:07:47 +03:00
committed by Simon Zolin
parent b519c3a83f
commit 67956597be
10 changed files with 467 additions and 30 deletions

View File

@@ -33,6 +33,10 @@ class ClientsTable extends Component {
} else {
config.upstreams = [];
}
if (values.tags) {
config.tags = values.tags.map(tag => tag.value);
}
}
if (this.props.modalType === MODAL_TYPE.EDIT) {
@@ -40,22 +44,29 @@ class ClientsTable extends Component {
} else {
this.handleFormAdd(config);
}
this.props.getStats();
};
getOptionsWithLabels = options => (
options.map(option => ({ value: option, label: option }))
);
getClient = (name, clients) => {
const client = clients.find(item => name === item.name);
if (client) {
const { upstreams, whois_info, ...values } = client;
const {
upstreams, tags, whois_info, ...values
} = client;
return {
upstreams: (upstreams && upstreams.join('\n')) || '',
tags: (tags && this.getOptionsWithLabels(tags)) || [],
...values,
};
}
return {
ids: [''],
tags: [],
use_global_settings: true,
use_global_blocked_services: true,
};
@@ -160,6 +171,30 @@ class ClientsTable extends Component {
);
},
},
{
Header: this.props.t('tags_title'),
accessor: 'tags',
minWidth: 140,
Cell: (row) => {
const { value } = row;
if (!value || value.length < 1) {
return '';
}
return (
<div className="logs__row logs__row--overflow">
<span className="logs__text">
{value.map(tag => (
<div key={tag} title={tag} className="small">
{tag}
</div>
))}
</span>
</div>
);
},
},
{
Header: this.props.t('requests_count'),
id: 'statistics',
@@ -223,9 +258,11 @@ class ClientsTable extends Component {
toggleClientModal,
processingAdding,
processingUpdating,
supportedTags,
} = this.props;
const currentClientData = this.getClient(modalClientName, clients);
const tagsOptions = this.getOptionsWithLabels(supportedTags);
return (
<Card
@@ -272,6 +309,7 @@ class ClientsTable extends Component {
handleSubmit={this.handleSubmit}
processingAdding={processingAdding}
processingUpdating={processingUpdating}
tagsOptions={tagsOptions}
/>
</Fragment>
</Card>
@@ -294,6 +332,7 @@ ClientsTable.propTypes = {
processingDeleting: PropTypes.bool.isRequired,
processingUpdating: PropTypes.bool.isRequired,
getStats: PropTypes.func.isRequired,
supportedTags: PropTypes.array.isRequired,
};
export default withNamespaces()(ClientsTable);

View File

@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import { Field, FieldArray, reduxForm, formValueSelector } from 'redux-form';
import { Trans, withNamespaces } from 'react-i18next';
import flow from 'lodash/flow';
import Select from 'react-select';
import i18n from '../../../i18n';
import Tabs from '../../ui/Tabs';
@@ -99,6 +100,23 @@ const renderFieldsWrapper = (placeholder, buttonTitle) =>
// Should create function outside of component to prevent component re-renders
const renderFields = renderFieldsWrapper(i18n.t('form_enter_id'), i18n.t('form_add_id'));
const renderMultiselect = (props) => {
const { input, placeholder, options } = props;
return (
<Select
{...input}
options={options}
className="basic-multi-select"
classNamePrefix="select"
onChange={value => input.onChange(value)}
onBlur={() => input.onBlur(input.value)}
placeholder={placeholder}
isMulti
/>
);
};
let Form = (props) => {
const {
t,
@@ -113,6 +131,7 @@ let Form = (props) => {
processingAdding,
processingUpdating,
invalid,
tagsOptions,
} = props;
return (
@@ -131,6 +150,27 @@ let Form = (props) => {
/>
</div>
<div className="form__group mb-4">
<div className="form__label">
<strong className="mr-3">
<Trans>tags_title</Trans>
</strong>
</div>
<div className="form__desc mt-0 mb-2">
<Trans components={[
<a href="https://github.com/AdguardTeam/AdGuardHome/wiki/Hosts-Blocklists#ctag" key="0">link</a>,
]}>
tags_desc
</Trans>
</div>
<Field
name="tags"
component={renderMultiselect}
placeholder={t('form_select_tags')}
options={tagsOptions}
/>
</div>
<div className="form__group">
<div className="form__label">
<strong className="mr-3">
@@ -286,6 +326,7 @@ Form.propTypes = {
processingAdding: PropTypes.bool.isRequired,
processingUpdating: PropTypes.bool.isRequired,
invalid: PropTypes.bool.isRequired,
tagsOptions: PropTypes.array.isRequired,
};
const selector = formValueSelector('clientForm');

View File

@@ -33,6 +33,7 @@ const Modal = (props) => {
toggleClientModal,
processingAdding,
processingUpdating,
tagsOptions,
} = props;
const initialData = getInitialData(currentClientData);
@@ -62,6 +63,7 @@ const Modal = (props) => {
toggleClientModal={toggleClientModal}
processingAdding={processingAdding}
processingUpdating={processingUpdating}
tagsOptions={tagsOptions}
/>
</div>
</ReactModal>
@@ -76,6 +78,7 @@ Modal.propTypes = {
toggleClientModal: PropTypes.func.isRequired,
processingAdding: PropTypes.bool.isRequired,
processingUpdating: PropTypes.bool.isRequired,
tagsOptions: PropTypes.array.isRequired,
};
export default withNamespaces()(Modal);

View File

@@ -46,6 +46,7 @@ class Clients extends Component {
processingDeleting={clients.processingDeleting}
processingUpdating={clients.processingUpdating}
getStats={getStats}
supportedTags={dashboard.supportedTags}
/>
<AutoClients
autoClients={dashboard.autoClients}