-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Telegram channel id on ethical metrics implementation #1890
Changes from all commits
f08ca8f
b733d88
b2896dd
b34f82b
2535c88
c10b191
f05b67a
79eb0a5
63679f8
f469045
564e930
a0b2d6e
fea766b
13e2bd9
f0f77a6
373962c
545eb5d
e5d714f
268704c
0f96394
071f367
31935a6
e0d8089
3fe1dc7
2aee5a9
221a138
59fa0a9
7b13a27
6e95db8
2fd9f04
60bde81
291bb63
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,7 +81,7 @@ | |
|
||
span { | ||
font-weight: bold; | ||
color: #0aa1da; | ||
color: var(--dappnode-strong-main-color); | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,14 @@ | ||
import React, { useEffect, useState } from "react"; | ||
import BottomButtons from "../BottomButtons"; | ||
import SwitchBig from "components/SwitchBig"; | ||
import { api } from "api"; | ||
import { api, useApi } from "api"; | ||
import Input from "components/Input"; | ||
import { docsUrl } from "params"; | ||
import Button from "components/Button"; | ||
import { Accordion } from "react-bootstrap"; | ||
import { BsInfoCircleFill } from "react-icons/bs"; | ||
import { IoIosArrowUp, IoIosArrowDown } from "react-icons/io"; | ||
import "./enableEthicalMetrics.scss"; | ||
|
||
export default function EnableEthicalMetrics({ | ||
onBack, | ||
|
@@ -12,43 +17,202 @@ export default function EnableEthicalMetrics({ | |
onBack?: () => void; | ||
onNext: () => void; | ||
}) { | ||
const ethicalMetricsConfig = useApi.getEthicalMetricsConfig(); | ||
const [ethicalMetricsOn, setEthicalMetricsOn] = useState(false); | ||
const [mail, setMail] = useState(""); | ||
const [mailError, setMailError] = useState(false); | ||
const [tgChannelId, setTgChannelId] = useState(""); | ||
const [tgChannelIdError, setTgChannelIdError] = useState(false); | ||
const [validationMessage, setValidationMessage] = useState(""); | ||
const [tgAccordionOpen, setTgAccordionOpen] = useState(false); | ||
|
||
// regex for email validation | ||
// useEffect to populate email field when data is available | ||
useEffect(() => { | ||
const ethicalMetricsData = ethicalMetricsConfig.data; | ||
if (ethicalMetricsData) { | ||
setMail(ethicalMetricsData.mail || ""); | ||
setTgChannelId(ethicalMetricsData.tgChannelId || ""); | ||
setEthicalMetricsOn(ethicalMetricsData.enabled); | ||
} | ||
}, [ethicalMetricsConfig.data]); | ||
|
||
// effect and regex for email validation | ||
useEffect(() => { | ||
const regex = /\S+@\S+\.\S+/; | ||
if (regex.test(mail)) { | ||
if (regex.test(mail) || mail === "") { | ||
setMailError(false); | ||
setEthicalMetricsOn(true); | ||
} else { | ||
setMailError(true); | ||
setEthicalMetricsOn(false); | ||
} | ||
}, [mail]); | ||
|
||
function onSetEnabeEthicalMetrics() { | ||
if (ethicalMetricsOn) | ||
api | ||
.enableEthicalMetrics({ mail, tgChannelId: null, sync: false }) | ||
.catch(e => { | ||
console.error(`Error on autoUpdateSettingsEdit : ${e.stack}`); | ||
}); | ||
onNext(); | ||
// effect and regex for telegram channelId validation | ||
useEffect(() => { | ||
const regex = /^-100\d{10}$/; | ||
if (regex.test(tgChannelId) || tgChannelId === "") { | ||
setTgChannelIdError(false); | ||
} else { | ||
setTgChannelIdError(true); | ||
} | ||
}, [tgChannelId]); | ||
|
||
async function enableEthicalMetricsSync() { | ||
try { | ||
setValidationMessage("Enabling ethical metrics..."); | ||
await api.enableEthicalMetrics({ | ||
mail: mail ? mail : null, | ||
tgChannelId: tgChannelId ? tgChannelId : null, | ||
sync: true | ||
}); | ||
setEthicalMetricsOn(true); | ||
setValidationMessage("Ethical metrics enabled successfully."); | ||
await ethicalMetricsConfig.revalidate(); | ||
} catch (error) { | ||
setValidationMessage("Error enabling ethical metrics."); | ||
console.error("Error enabling ethical metrics:", error); | ||
} | ||
} | ||
|
||
// clear the success message after 5 seconds | ||
useEffect(() => { | ||
if (validationMessage === "Ethical metrics enabled successfully.") { | ||
const timer = setTimeout(() => { | ||
setValidationMessage(""); | ||
}, 5000); | ||
return () => clearTimeout(timer); | ||
} | ||
}, [validationMessage]); | ||
|
||
function toggleEthicalSwitch() { | ||
if (!ethicalMetricsOn) { | ||
enableEthicalMetricsSync(); | ||
} | ||
setEthicalMetricsOn(!ethicalMetricsOn); | ||
} | ||
|
||
return ( | ||
<> | ||
<div className="ethical-container"> | ||
<div className="header"> | ||
<div className="title">Enable system notifications</div> | ||
<div className="title">Enable System Notifications</div> | ||
<div className="description"> | ||
Enable ethical metrics and receive alerts whenever your dappnode is | ||
down without losing your privacy.{" "} | ||
<a href={docsUrl.ethicalMetricsOverview}>Learn more</a> | ||
<p className="description-text"> | ||
<span className="highlight">Enable ethical metrics</span> and | ||
receive alerts whenever your dappnode is down without compromising | ||
your privacy. | ||
<span className="note"> | ||
{" "} | ||
Note: Ethical Metrics requires the Dappnode Monitoring Service | ||
(DMS) as a dependency. | ||
</span>{" "} | ||
<a href={docsUrl.ethicalMetricsOverview} className="learn-more"> | ||
Learn more | ||
</a> | ||
</p> | ||
</div> | ||
</div> | ||
|
||
<p className="instructions"> | ||
<strong>Telegram notifications are available!</strong> Enter your{" "} | ||
<strong>Telegram Channel ID</strong> to receive reliable alerts | ||
promptly. | ||
</p> | ||
<em className="advice"> | ||
<strong>Advice: </strong> We highly recommend using the Telegram channel | ||
option (or both) rather than relying only on email notifications. Email | ||
notifications may be categorized as spam, potentially causing you to | ||
miss important notifications! | ||
</em> | ||
{!ethicalMetricsOn && ( | ||
<span | ||
style={{ | ||
fontStyle: "italic", | ||
fontSize: "14px", | ||
color: "var(--dappnode-strong-main-color)" | ||
}} | ||
> | ||
You must provide a Telegram channel ID or an email to enable ethical | ||
metrics notifications | ||
</span> | ||
)} | ||
<span>Ethical metrics notifications by telegram channel</span> | ||
<div> | ||
<Input | ||
prepend="Telegram" | ||
value={tgChannelId} | ||
onValueChange={setTgChannelId} | ||
isInvalid={tgChannelIdError} | ||
required={true} | ||
placeholder="-100XXXXXXXXXX" | ||
/> | ||
<Accordion defaultActiveKey={tgAccordionOpen ? "0" : ""}> | ||
<div className="accordion-modal-wrapper"> | ||
<Accordion.Toggle | ||
eventKey="0" | ||
onClick={() => setTgAccordionOpen(!tgAccordionOpen)} | ||
className="accordion-modal" | ||
> | ||
<div className="header"> | ||
<BsInfoCircleFill | ||
className="links-icon" | ||
style={{ fontSize: "14px" }} | ||
/> | ||
How can I get a Telegram channel Id?{" "} | ||
{tgAccordionOpen ? <IoIosArrowUp /> : <IoIosArrowDown />}{" "} | ||
</div> | ||
</Accordion.Toggle> | ||
<Accordion.Collapse eventKey="0"> | ||
<div> | ||
<ol> | ||
<li> | ||
Open{" "} | ||
<a | ||
href="https://web.telegram.org/a/" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
Telegram web | ||
</a> | ||
. | ||
<ul> | ||
<li> | ||
Ensure the URL ends with <span>/a/</span>. If not, | ||
manually add <span>/a/</span> after{" "} | ||
<span>https://web.telegram.org</span>.{" "} | ||
</li> | ||
</ul> | ||
</li> | ||
<li>Create a private channel.</li> | ||
<li> | ||
Add <span>@ethicalMetricsAlerts_bot</span> as an | ||
administrator in the channel. | ||
</li> | ||
<li> | ||
Go to your channel and copy the 13-digit ID from the URL. | ||
<ul> | ||
<li> | ||
The channel ID always starts with <span>-100</span>. | ||
Ensure to include the <span>-</span> when coping it. | ||
</li> | ||
</ul> | ||
</li> | ||
|
||
<li> | ||
Paste the ID into the Telegram Channel ID field and enable | ||
Ethical Metrics to receive notifications. | ||
</li> | ||
</ol> | ||
</div> | ||
</Accordion.Collapse> | ||
</div> | ||
</Accordion> | ||
</div> | ||
{tgChannelIdError && ( | ||
<span style={{ fontSize: "12px", color: "red" }}> | ||
Telegram channel ID format is incorrect | ||
</span> | ||
)} | ||
|
||
<span>Ethical metrics notifications by email</span> | ||
<Input | ||
prepend="Email" | ||
value={mail} | ||
|
@@ -57,19 +221,64 @@ export default function EnableEthicalMetrics({ | |
required={true} | ||
placeholder="example@email.com" | ||
/> | ||
{mailError && ( | ||
<span style={{ fontSize: "12px", color: "red" }}> | ||
Email format is incorrect | ||
</span> | ||
)} | ||
|
||
{/* This top div prevents the card from stretching vertically */} | ||
<div> | ||
<SwitchBig | ||
disabled={mailError} | ||
checked={ethicalMetricsOn} | ||
onChange={setEthicalMetricsOn} | ||
label="Enable system notifications" | ||
id="enable-ethical-metrics" | ||
/> | ||
{ethicalMetricsOn ? ( | ||
// Render the "Update" button if ethical metrics are enabled | ||
<div className="update-button"> | ||
<Button | ||
type="submit" | ||
onClick={async () => { | ||
setValidationMessage(""); | ||
await enableEthicalMetricsSync(); | ||
}} | ||
variant="dappnode" | ||
disabled={ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you try to simplify this condition? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it looks a bit complex |
||
// No input provided or both inputs have errors | ||
(tgChannelId === "" && mail === "") || | ||
(tgChannelIdError && mailError) || | ||
// Only tgChannelId has error or only mail has error | ||
(tgChannelIdError && mail === "") || | ||
(tgChannelId === "" && mailError) || | ||
// No changes in mail or tgChannelId | ||
(mail === ethicalMetricsConfig.data?.mail && | ||
(tgChannelId === "" || | ||
tgChannelId === ethicalMetricsConfig.data?.tgChannelId || | ||
tgChannelIdError)) || | ||
// Asynchronous operation in progress | ||
validationMessage !== "" | ||
} | ||
> | ||
Update | ||
</Button> | ||
</div> | ||
) : ( | ||
<SwitchBig | ||
disabled={ | ||
(tgChannelId === "" && mail === "") || | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
(tgChannelIdError && mailError) || | ||
(tgChannelIdError && mail === "") || | ||
(tgChannelId === "" && mailError) | ||
} | ||
checked={ethicalMetricsOn} | ||
onChange={toggleEthicalSwitch} | ||
label="" | ||
id="enable-ethical-metrics" | ||
/> | ||
)} | ||
</div> | ||
|
||
<BottomButtons onBack={onBack} onNext={onSetEnabeEthicalMetrics} /> | ||
</> | ||
<BottomButtons onBack={onBack} onNext={() => onNext()} /> | ||
|
||
{validationMessage && ( | ||
<p className="validation-message">{validationMessage}</p> | ||
)} | ||
</div> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you test the behaviour of setting this with option
sync
to true? Take into account that this might be the onboarding and might take some time the user would not like to wait during setting up dappnode