* client: add icons for table buttons

This commit is contained in:
Ildar Kamalov 2019-05-23 12:32:51 +03:00 committed by Simon Zolin
parent bd2c4269db
commit cbef338592
10 changed files with 65 additions and 24 deletions

View File

@ -270,11 +270,12 @@
"clients_desc": "Configure devices connected to AdGuard Home", "clients_desc": "Configure devices connected to AdGuard Home",
"settings_global": "Global", "settings_global": "Global",
"settings_custom": "Custom", "settings_custom": "Custom",
"add_client": "Add Client",
"table_client": "Client", "table_client": "Client",
"table_name": "Name", "table_name": "Name",
"save_btn": "Save", "save_btn": "Save",
"client_add": "Add Client",
"client_new": "New Client", "client_new": "New 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 or MAC address. 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 or MAC address. Please note, that using MAC as identifier is possible only if AdGuard Home is also a <0>DHCP server</0>",

View File

@ -21,6 +21,7 @@ import Status from '../ui/Status';
import UpdateTopline from '../ui/UpdateTopline'; import UpdateTopline from '../ui/UpdateTopline';
import UpdateOverlay from '../ui/UpdateOverlay'; import UpdateOverlay from '../ui/UpdateOverlay';
import EncryptionTopline from '../ui/EncryptionTopline'; import EncryptionTopline from '../ui/EncryptionTopline';
import Icons from '../ui/Icons';
import i18n from '../../i18n'; import i18n from '../../i18n';
class App extends Component { class App extends Component {
@ -103,6 +104,7 @@ class App extends Component {
</div> </div>
<Footer /> <Footer />
<Toasts /> <Toasts />
<Icons />
</Fragment> </Fragment>
</HashRouter> </HashRouter>
); );

View File

@ -1,13 +0,0 @@
.remove-icon {
position: relative;
top: 2px;
display: inline-block;
width: 20px;
height: 18px;
opacity: 0.6;
}
.remove-icon:hover {
cursor: pointer;
opacity: 1;
}

View File

@ -6,7 +6,6 @@ import Modal from '../ui/Modal';
import PageTitle from '../ui/PageTitle'; import PageTitle from '../ui/PageTitle';
import Card from '../ui/Card'; import Card from '../ui/Card';
import UserRules from './UserRules'; import UserRules from './UserRules';
import './Filters.css';
class Filters extends Component { class Filters extends Component {
componentDidMount() { componentDidMount() {
@ -59,7 +58,18 @@ class Filters extends Component {
}, { }, {
Header: <Trans>actions_table_header</Trans>, Header: <Trans>actions_table_header</Trans>,
accessor: 'url', accessor: 'url',
Cell: ({ value }) => (<span title={ this.props.t('delete_table_action') } className='remove-icon fe fe-trash-2' onClick={() => this.props.removeFilter(value)}/>), Cell: ({ value }) => (
<button
type="button"
className="btn btn-icon btn-outline-secondary btn-sm"
onClick={() => this.props.removeFilter(value)}
title={this.props.t('delete_table_action')}
>
<svg className="icons">
<use xlinkHref="#delete" />
</svg>
</button>
),
className: 'text-center', className: 'text-center',
width: 80, width: 80,
sortable: false, sortable: false,

View File

@ -103,7 +103,9 @@ let Form = (props) => {
</div> </div>
<div className="mb-4"> <div className="mb-4">
<strong>Settings</strong> <strong>
<Trans>settings</Trans>
</strong>
</div> </div>
<div className="form__group"> <div className="form__group">

View File

@ -3,11 +3,13 @@ import PropTypes from 'prop-types';
import { Trans, withNamespaces } from 'react-i18next'; import { Trans, withNamespaces } from 'react-i18next';
import ReactModal from 'react-modal'; import ReactModal from 'react-modal';
import { MODAL_TYPE } from '../../../helpers/constants';
import Form from './Form'; import Form from './Form';
const Modal = (props) => { const Modal = (props) => {
const { const {
isModalOpen, isModalOpen,
modalType,
currentClientData, currentClientData,
handleSubmit, handleSubmit,
toggleClientModal, toggleClientModal,
@ -25,7 +27,11 @@ const Modal = (props) => {
<div className="modal-content"> <div className="modal-content">
<div className="modal-header"> <div className="modal-header">
<h4 className="modal-title"> <h4 className="modal-title">
<Trans>client_new</Trans> {modalType === MODAL_TYPE.EDIT ? (
<Trans>client_edit</Trans>
) : (
<Trans>client_new</Trans>
)}
</h4> </h4>
<button type="button" className="close" onClick={() => toggleClientModal()}> <button type="button" className="close" onClick={() => toggleClientModal()}>
<span className="sr-only">Close</span> <span className="sr-only">Close</span>
@ -47,6 +53,7 @@ const Modal = (props) => {
Modal.propTypes = { Modal.propTypes = {
isModalOpen: PropTypes.bool.isRequired, isModalOpen: PropTypes.bool.isRequired,
modalType: PropTypes.string.isRequired,
currentClientData: PropTypes.object.isRequired, currentClientData: PropTypes.object.isRequired,
handleSubmit: PropTypes.func.isRequired, handleSubmit: PropTypes.func.isRequired,
toggleClientModal: PropTypes.func.isRequired, toggleClientModal: PropTypes.func.isRequired,

View File

@ -139,19 +139,21 @@ class Clients extends Component {
{ {
Header: this.props.t('actions_table_header'), Header: this.props.t('actions_table_header'),
accessor: 'actions', accessor: 'actions',
maxWidth: 150,
Cell: (row) => { Cell: (row) => {
const clientName = row.original.name; const clientName = row.original.name;
const { const {
toggleClientModal, toggleClientModal,
processingDeleting, processingDeleting,
processingUpdating, processingUpdating,
t,
} = this.props; } = this.props;
return ( return (
<div className="logs__row logs__row--center"> <div className="logs__row logs__row--center">
<button <button
type="button" type="button"
className="btn btn-outline-primary btn-sm mr-2" className="btn btn-icon btn-outline-primary btn-sm mr-2"
onClick={() => onClick={() =>
toggleClientModal({ toggleClientModal({
type: MODAL_TYPE.EDIT, type: MODAL_TYPE.EDIT,
@ -159,16 +161,22 @@ class Clients extends Component {
}) })
} }
disabled={processingUpdating} disabled={processingUpdating}
title={t('edit_table_action')}
> >
<Trans>edit_table_action</Trans> <svg className="icons">
<use xlinkHref="#edit" />
</svg>
</button> </button>
<button <button
type="button" type="button"
className="btn btn-outline-secondary btn-sm" className="btn btn-icon btn-outline-secondary btn-sm"
onClick={() => this.handleDelete({ name: clientName })} onClick={() => this.handleDelete({ name: clientName })}
disabled={processingDeleting} disabled={processingDeleting}
title={t('delete_table_action')}
> >
<Trans>delete_table_action</Trans> <svg className="icons">
<use xlinkHref="#delete" />
</svg>
</button> </button>
</div> </div>
); );
@ -181,6 +189,7 @@ class Clients extends Component {
t, t,
clients, clients,
isModalOpen, isModalOpen,
modalType,
modalClientName, modalClientName,
toggleClientModal, toggleClientModal,
processingAdding, processingAdding,
@ -203,7 +212,6 @@ class Clients extends Component {
showPagination={true} showPagination={true}
defaultPageSize={10} defaultPageSize={10}
minRows={5} minRows={5}
resizable={false}
previousText={t('previous_btn')} previousText={t('previous_btn')}
nextText={t('next_btn')} nextText={t('next_btn')}
loadingText={t('loading_table_status')} loadingText={t('loading_table_status')}
@ -218,11 +226,12 @@ class Clients extends Component {
onClick={() => toggleClientModal(MODAL_TYPE.ADD)} onClick={() => toggleClientModal(MODAL_TYPE.ADD)}
disabled={processingAdding} disabled={processingAdding}
> >
<Trans>add_client</Trans> <Trans>client_add</Trans>
</button> </button>
<Modal <Modal
isModalOpen={isModalOpen} isModalOpen={isModalOpen}
modalType={modalType}
toggleClientModal={toggleClientModal} toggleClientModal={toggleClientModal}
currentClientData={currentClientData} currentClientData={currentClientData}
handleSubmit={this.handleSubmit} handleSubmit={this.handleSubmit}

View File

@ -76,3 +76,11 @@
.encryption__list li { .encryption__list li {
list-style: inside; list-style: inside;
} }
.btn-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
}

View File

@ -0,0 +1,5 @@
.icons {
display: inline-block;
vertical-align: middle;
height: 100%;
}

View File

@ -1,5 +1,7 @@
import React from 'react'; import React from 'react';
import './Icons.css';
const Icons = () => ( const Icons = () => (
<svg xmlns="http://www.w3.org/2000/svg" className="hidden"> <svg xmlns="http://www.w3.org/2000/svg" className="hidden">
<symbol id="android" viewBox="0 0 14 16" fill="currentColor"> <symbol id="android" viewBox="0 0 14 16" fill="currentColor">
@ -21,6 +23,14 @@ const Icons = () => (
<symbol id="router" viewBox="0 0 30 30" fill="currentColor"> <symbol id="router" viewBox="0 0 30 30" fill="currentColor">
<path d="M17.646 2.332a1 1 0 0 0-.697 1.719 6.984 6.984 0 0 1 0 9.898 1 1 0 1 0 1.414 1.414c3.507-3.506 3.507-9.22 0-12.726a1 1 0 0 0-.717-.305zm-12.662.654A1 1 0 0 0 4 4v14a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h22a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2H12V9a1 1 0 0 0-1.016-1.014A1 1 0 0 0 10 9v9H6V4a1 1 0 0 0-1.016-1.014zm9.834 2.176a1 1 0 0 0-.697 1.717 2.985 2.985 0 0 1 0 4.242 1 1 0 1 0 1.414 1.414 5.014 5.014 0 0 0 0-7.07 1 1 0 0 0-.717-.303zM5 21a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2z" /> <path d="M17.646 2.332a1 1 0 0 0-.697 1.719 6.984 6.984 0 0 1 0 9.898 1 1 0 1 0 1.414 1.414c3.507-3.506 3.507-9.22 0-12.726a1 1 0 0 0-.717-.305zm-12.662.654A1 1 0 0 0 4 4v14a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h22a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2H12V9a1 1 0 0 0-1.016-1.014A1 1 0 0 0 10 9v9H6V4a1 1 0 0 0-1.016-1.014zm9.834 2.176a1 1 0 0 0-.697 1.717 2.985 2.985 0 0 1 0 4.242 1 1 0 1 0 1.414 1.414 5.014 5.014 0 0 0 0-7.07 1 1 0 0 0-.717-.303zM5 21a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2z" />
</symbol> </symbol>
<symbol id="edit" viewBox="0 0 24 24" stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2">
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
</symbol>
<symbol id="delete" viewBox="0 0 24 24" stroke="currentColor" fill="none" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2">
<path d="m3 6h2 16"/><path d="m19 6v14a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2-2v-14m3 0v-2a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="m10 11v6"/><path d="m14 11v6"/>
</symbol>
</svg> </svg>
); );