Pull request: 1333-protection-pause vol.1
Merge in DNS/adguard-home from 1333-protection-pause-1 to master Squashed commit of the following: commit 5ff98385bc5ff66e214d80782eb4dc41e344aa38 Merge: 97f94a540bc3ef89Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri Mar 24 19:08:21 2023 +0700 Merge remote-tracking branch 'origin/master' into 1333-protection-pause-1 commit 97f94a5498ac221f88f2f7dfef4b255f4945329e Author: Arseny Lisin <a.lisin@adguard.com> Date: Fri Mar 24 13:03:20 2023 +0200 Fix protection timer bugs commit 1cc61af1996bd803f3fa638cb9e2388470072bf0 Merge: 5a144ea3 235ce458 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Thu Mar 23 22:27:47 2023 +0700 Merge remote-tracking branch 'origin/1333-protection-pause-1' into 1333-protection-pause-1 commit 5a144ea3a48c3d0d5e57dd14232ab7a8e77a8c1e Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Thu Mar 23 22:25:08 2023 +0700 dnsforward: imp code commit 235ce458a62b3152f36e32580ed0226a56580ec6 Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Thu Mar 23 17:35:06 2023 +0300 dnsforward: imp locks commit 0ea3a0a176b810a2b3f0b307aa406fe1670c9219 Merge: 52f66810df61741fAuthor: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Thu Mar 23 19:30:41 2023 +0700 Merge remote-tracking branch 'origin/master' into 1333-protection-pause-1 # Conflicts: # CHANGELOG.md # openapi/CHANGELOG.md commit 52f668109673286a50909c042e6352cd803e8eed Merge: 9a7eb7b3306c1983Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Thu Mar 23 11:23:50 2023 +0700 Merge remote-tracking branch 'origin/master' into 1333-protection-pause-1 # Conflicts: # CHANGELOG.md # internal/dnsforward/http.go commit 9a7eb7b3ab2b5f6ad321aa3245d33839c3aa6fbd Author: Arseny Lisin <a.lisin@adguard.com> Date: Wed Mar 22 06:56:55 2023 +0200 Review fix commit 5612d51252ba91842bd6811baec1c91136bb3bf2 Merge: c0a918a5c3edab43Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Tue Mar 21 22:00:39 2023 +0700 Merge remote-tracking branch 'origin/master' into 1333-protection-pause-1 # Conflicts: # client/src/__locales/en.json commit c0a918a518ad9b37041aed159d215516258bc987 Author: Arseny Lisin <a.lisin@adguard.com> Date: Tue Mar 21 12:13:18 2023 +0200 Review fix commit 34faa61cc1e6210a612e7a2f4895a1504df37680 Author: Arseny Lisin <a.lisin@adguard.com> Date: Tue Mar 21 10:43:37 2023 +0200 Fix props to new api commit 158e582373863495f0e0ca177d7b365cc66ad671 Author: Arseny Lisin <a.lisin@adguard.com> Date: Mon Mar 20 18:44:34 2023 +0200 Review fix commit 9e8b8c3778b8e1dfad0d39e44f70886dfd3aeb9a Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon Mar 20 22:31:28 2023 +0700 all: docs commit 761a203f53b535ca235cfe62f289bd0e02b90be2 Merge: d0b0723148431f8bAuthor: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon Mar 20 22:26:13 2023 +0700 Merge remote-tracking branch 'origin/master' into 1333-protection-pause-1 commit d0b07231b6f29b534930f1fcfc82b4934c295ff8 Merge: ea448760a2053526Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon Mar 13 13:00:52 2023 +0700 Merge remote-tracking branch 'origin/master' into 1333-protection-pause-1 # Conflicts: # CHANGELOG.md # client/src/components/App/index.css # internal/dnsforward/config.go commit ea4487608a9c81d25f155ff63fee7c9dcf21f448 Merge: dfd0f33fa556ce8fAuthor: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Tue Feb 21 11:54:27 2023 +0700 Merge remote-tracking branch 'origin/master' into 1333-protection-pause-1 # Conflicts: # CHANGELOG.md commit dfd0f33fb474d497cbc9237ee466276728eea397 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Tue Feb 21 11:51:40 2023 +0700 all: docs commit d36df96fba8c6d923faef85c198b6bd0743b7ee8 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon Feb 20 12:41:49 2023 +0700 all: safesearch commit 60f2ceec563221337f34bb60baa96aa2b2429c40 Merge: 7c5144276f6ced33Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon Feb 20 12:30:42 2023 +0700 Merge remote-tracking branch 'origin/master' into 1333-protection-pause-1 # Conflicts: # CHANGELOG.md commit 7c514427e77c5b09d8e148c78220a71046e68cd1 Merge: 0fa4ff994d295a38Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Thu Feb 16 11:55:21 2023 +0700 Merge remote-tracking branch 'origin/master' into 1333-protection-pause-1 # Conflicts: # CHANGELOG.md ... and 26 more commits
This commit is contained in:
@@ -43,6 +43,7 @@ import DnsRewrites from '../../containers/DnsRewrites';
|
||||
import CustomRules from '../../containers/CustomRules';
|
||||
import Services from '../Filters/Services';
|
||||
import Logs from '../Logs';
|
||||
import ProtectionTimer from '../ProtectionTimer';
|
||||
|
||||
const ROUTES = [
|
||||
{
|
||||
@@ -191,6 +192,7 @@ const App = () => {
|
||||
{!processingEncryption && <EncryptionTopline />}
|
||||
<LoadingBar className="loading-bar" updateTime={1000} />
|
||||
<Header />
|
||||
<ProtectionTimer />
|
||||
<div className="container container--wrap pb-5">
|
||||
{processing && <Loading />}
|
||||
{!isCoreRunning && <div className="row row-cards">
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
.dashboard-protection-button.btn-gray {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
border-right-color: #a4a4a4;
|
||||
}
|
||||
|
||||
.stats__table .popover__body {
|
||||
left: -10px;
|
||||
min-width: 270px;
|
||||
@@ -34,20 +40,11 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dashboard-title__button {
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.page-title--dashboard {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.dashboard-title__button {
|
||||
margin: 0.5rem 0;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.counters__row {
|
||||
|
||||
@@ -9,18 +9,20 @@ import Counters from './Counters';
|
||||
import Clients from './Clients';
|
||||
import QueriedDomains from './QueriedDomains';
|
||||
import BlockedDomains from './BlockedDomains';
|
||||
import { SETTINGS_URLS } from '../../helpers/constants';
|
||||
import { DISABLE_PROTECTION_TIMINGS, ONE_SECOND_IN_MS, SETTINGS_URLS } from '../../helpers/constants';
|
||||
import { msToSeconds, msToMinutes, msToHours } from '../../helpers/helpers';
|
||||
|
||||
import PageTitle from '../ui/PageTitle';
|
||||
import Loading from '../ui/Loading';
|
||||
import './Dashboard.css';
|
||||
import Dropdown from '../ui/Dropdown';
|
||||
|
||||
const Dashboard = ({
|
||||
getAccessList,
|
||||
getStats,
|
||||
getStatsConfig,
|
||||
dashboard,
|
||||
dashboard: { protectionEnabled, processingProtection },
|
||||
dashboard: { protectionEnabled, processingProtection, protectionDisabledDuration },
|
||||
toggleProtection,
|
||||
stats,
|
||||
access,
|
||||
@@ -36,7 +38,6 @@ const Dashboard = ({
|
||||
useEffect(() => {
|
||||
getAllStats();
|
||||
}, []);
|
||||
|
||||
const getSubtitle = () => {
|
||||
if (stats.interval === 0) {
|
||||
return t('stats_disabled_short');
|
||||
@@ -47,9 +48,7 @@ const Dashboard = ({
|
||||
: t('for_last_days', { count: stats.interval });
|
||||
};
|
||||
|
||||
const buttonText = protectionEnabled ? 'disable_protection' : 'enable_protection';
|
||||
|
||||
const buttonClass = classNames('btn btn-sm dashboard-title__button', {
|
||||
const buttonClass = classNames('btn btn-sm dashboard-protection-button', {
|
||||
'btn-gray': protectionEnabled,
|
||||
'btn-success': !protectionEnabled,
|
||||
});
|
||||
@@ -71,16 +70,87 @@ const Dashboard = ({
|
||||
|
||||
const subtitle = getSubtitle();
|
||||
|
||||
const DISABLE_PROTECTION_ITEMS = [
|
||||
{
|
||||
text: t('disable_for_seconds', { count: msToSeconds(DISABLE_PROTECTION_TIMINGS.HALF_MINUTE) }),
|
||||
disableTime: DISABLE_PROTECTION_TIMINGS.HALF_MINUTE,
|
||||
},
|
||||
{
|
||||
text: t('disable_for_minutes', { count: msToMinutes(DISABLE_PROTECTION_TIMINGS.MINUTE) }),
|
||||
disableTime: DISABLE_PROTECTION_TIMINGS.MINUTE,
|
||||
},
|
||||
{
|
||||
text: t('disable_for_minutes', { count: msToMinutes(DISABLE_PROTECTION_TIMINGS.TEN_MINUTES) }),
|
||||
disableTime: DISABLE_PROTECTION_TIMINGS.TEN_MINUTES,
|
||||
},
|
||||
{
|
||||
text: t('disable_for_hours', { count: msToHours(DISABLE_PROTECTION_TIMINGS.HOUR) }),
|
||||
disableTime: DISABLE_PROTECTION_TIMINGS.HOUR,
|
||||
},
|
||||
{
|
||||
text: t('disable_until_tomorrow'),
|
||||
disableTime: DISABLE_PROTECTION_TIMINGS.TOMORROW,
|
||||
},
|
||||
];
|
||||
|
||||
const getDisableProtectionItems = () => (
|
||||
Object.values(DISABLE_PROTECTION_ITEMS)
|
||||
.map((item, index) => (
|
||||
<div
|
||||
key={`disable_timings_${index}`}
|
||||
className="dropdown-item"
|
||||
onClick={() => {
|
||||
toggleProtection(protectionEnabled, item.disableTime - ONE_SECOND_IN_MS);
|
||||
}}
|
||||
>
|
||||
{item.text}
|
||||
</div>
|
||||
))
|
||||
);
|
||||
|
||||
const getRemaningTimeText = (milliseconds) => {
|
||||
if (!milliseconds) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const date = new Date(milliseconds);
|
||||
const hh = date.getUTCHours();
|
||||
const mm = `0${date.getUTCMinutes()}`.slice(-2);
|
||||
const ss = `0${date.getUTCSeconds()}`.slice(-2);
|
||||
const formattedHH = `0${hh}`.slice(-2);
|
||||
|
||||
return hh ? `${formattedHH}:${mm}:${ss}` : `${mm}:${ss}`;
|
||||
};
|
||||
|
||||
const getProtectionBtnText = (status) => (status ? t('disable_protection') : t('enable_protection'));
|
||||
|
||||
return <>
|
||||
<PageTitle title={t('dashboard')} containerClass="page-title--dashboard">
|
||||
<button
|
||||
type="button"
|
||||
className={buttonClass}
|
||||
onClick={() => toggleProtection(protectionEnabled)}
|
||||
disabled={processingProtection}
|
||||
>
|
||||
<Trans>{buttonText}</Trans>
|
||||
</button>
|
||||
<div className="page-title__protection">
|
||||
<button
|
||||
type="button"
|
||||
className={buttonClass}
|
||||
onClick={() => {
|
||||
toggleProtection(protectionEnabled);
|
||||
}}
|
||||
disabled={processingProtection}
|
||||
>
|
||||
{protectionDisabledDuration
|
||||
? `${t('enable_protection_timer')} ${getRemaningTimeText(protectionDisabledDuration)}`
|
||||
: getProtectionBtnText(protectionEnabled)
|
||||
}
|
||||
</button>
|
||||
|
||||
{protectionEnabled && <Dropdown
|
||||
label=""
|
||||
baseClassName="dropdown-protection"
|
||||
icon="arrow-down"
|
||||
controlClassName="dropdown-protection__toggle"
|
||||
menuClassName="dropdown-menu dropdown-menu-arrow dropdown-menu--protection"
|
||||
>
|
||||
{getDisableProtectionItems()}
|
||||
</Dropdown>}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-outline-primary btn-sm"
|
||||
|
||||
52
client/src/components/ProtectionTimer/index.js
Normal file
52
client/src/components/ProtectionTimer/index.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import { useEffect } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { ONE_SECOND_IN_MS } from '../../helpers/constants';
|
||||
import { setProtectionTimerTime, toggleProtectionSuccess } from '../../actions';
|
||||
|
||||
let interval = null;
|
||||
|
||||
const ProtectionTimer = ({
|
||||
protectionDisabledDuration,
|
||||
toggleProtectionSuccess,
|
||||
setProtectionTimerTime,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
if (protectionDisabledDuration !== null && protectionDisabledDuration < ONE_SECOND_IN_MS) {
|
||||
toggleProtectionSuccess({ disabledDuration: null });
|
||||
}
|
||||
|
||||
if (protectionDisabledDuration) {
|
||||
interval = setInterval(() => {
|
||||
setProtectionTimerTime(protectionDisabledDuration - ONE_SECOND_IN_MS);
|
||||
}, ONE_SECOND_IN_MS);
|
||||
}
|
||||
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, [protectionDisabledDuration]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
ProtectionTimer.propTypes = {
|
||||
setProtectionTimerTime: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const { dashboard } = state;
|
||||
const { protectionEnabled, protectionDisabledDuration } = dashboard;
|
||||
return { protectionEnabled, protectionDisabledDuration };
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
toggleProtectionSuccess,
|
||||
setProtectionTimerTime,
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
)(ProtectionTimer);
|
||||
@@ -1,3 +1,7 @@
|
||||
.dropdown-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dropdown-item.active,
|
||||
.dropdown-item:active {
|
||||
background-color: var(--btn-success-bgcolor);
|
||||
@@ -6,3 +10,55 @@
|
||||
.dropdown-menu {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.dropdown-menu.dropdown-menu--protection {
|
||||
top: calc(100% + 8px);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.dropdown-menu.dropdown-menu-arrow.dropdown-menu--protection::before,
|
||||
.dropdown-menu.dropdown-menu-arrow.dropdown-menu--protection::after {
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.dropdown-protection {
|
||||
align-self: stretch;
|
||||
width: 26px;
|
||||
display: flex;
|
||||
position: relative;
|
||||
border: 1px solid #868e96;
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
border-left: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dropdown-protection__toggle {
|
||||
width: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
background-color: #868e96;
|
||||
transition: background-color 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.dropdown-protection__toggle:hover {
|
||||
background-color: #727b84;
|
||||
}
|
||||
|
||||
.dropdown-protection__toggle .nav-icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
color: var(--white);
|
||||
transition: 0.15s ease-in-out transform;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
.dropdown-protection.show .nav-icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
@@ -181,6 +181,12 @@ const Icons = () => (
|
||||
</svg>
|
||||
</symbol>
|
||||
|
||||
<symbol id="arrow-down" viewBox="0 0 24 24" fill="currentColor">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<path fillRule="evenodd" d="M6.2 8.2a.64.64 0 0 1 .94 0L12 13.32l4.86-5.1a.64.64 0 0 1 .94 0c.27.27.27.71 0 .98l-5.33 5.6a.64.64 0 0 1-.94 0L6.2 9.2a.72.72 0 0 1 0-.98Z" clipRule="evenodd"/>
|
||||
</svg>
|
||||
</symbol>
|
||||
|
||||
<symbol id="arrow-right" viewBox="0 0 24 24" stroke="currentColor"
|
||||
strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5">
|
||||
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
@@ -10216,6 +10216,18 @@ body.fixed-header .page {
|
||||
line-height: 2.5rem;
|
||||
}
|
||||
|
||||
.page-title__protection {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.page-title__protection {
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
.page-title-icon {
|
||||
color: #9aa0ac;
|
||||
font-size: 1.25rem;
|
||||
|
||||
Reference in New Issue
Block a user