From 9c5dfddeb031a7b32b1990c2b215930ac8cc9d10 Mon Sep 17 00:00:00 2001 From: Sarath Date: Wed, 28 Dec 2022 06:55:05 -0500 Subject: [PATCH] Improve MAT conditional filters (#752) * Drop fields from MAT form state when they are hidden * Hide irrelevant options in X and Y axis based on test name * Show Y axis countries option when All Countries selected * Remove console log * Improve handling of conditional filters Co-authored-by: Maja Komel --- components/aggregation/mat/Form.js | 75 ++++++++++++++++++------------ pages/_app.js | 2 +- public/static/lang/en.json | 6 +-- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/components/aggregation/mat/Form.js b/components/aggregation/mat/Form.js index d9863b560..9f7b0202d 100644 --- a/components/aggregation/mat/Form.js +++ b/components/aggregation/mat/Form.js @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState, useRef, useLayoutEffect } from 'react' +import React, { useCallback, useEffect, useState, useMemo } from 'react' import PropTypes from 'prop-types' import { useForm, Controller } from 'react-hook-form' import styled from 'styled-components' @@ -55,18 +55,17 @@ const messages = defineMessages({ const xAxisOptions = [ - 'measurement_start_day', - 'category_code', - 'probe_cc', + ['measurement_start_day', [], false], + ['category_code', ['web_connectivity'], false], + ['probe_cc', [], true], ] const yAxisOptions = [ - 'domain', - 'input', - 'category_code', - 'probe_cc', - 'probe_asn', - '' + ['domain', ['web_connectivity'], false], + ['category_code', ['web_connectivity'], false], + ['probe_cc', [], true], + ['probe_asn', [], false], + ['', [], false] ] const testsWithValidDomainFilter = [ @@ -76,6 +75,15 @@ const testsWithValidDomainFilter = [ 'tcp_connect' ] +const filterAxisOptions = (options, countryValue, testNameValue) => { + return options + .filter(([option, validTestNames, hideForSingleCountry]) => { + if (hideForSingleCountry && countryValue !== '') return false + return validTestNames.length === 0 || validTestNames.includes(testNameValue) + }) + .map(([option]) => option) +} + function isValidFilterForTestname(testName = 'XX', arrayWithMapping) { // whether the dependent filter is valid to show along with `testName` return arrayWithMapping.includes(testName) @@ -99,36 +107,27 @@ const defaultDefaultValues = { } export const Form = ({ onSubmit, testNames, query }) => { - const isInitialMount = useRef(true) const intl = useIntl() const [showConfirmation, setShowConfirmation] = useState(false) const defaultValues = Object.assign({}, defaultDefaultValues, query) const { handleSubmit, control, getValues, watch, reset, setValue } = useForm({ - defaultValues + defaultValues, + shouldUnregister: true, }) - // If `query` changes after the page mounts, reset the form to use default - // values based on new `query` - useEffect(() => { - // Skip running this on mount to avoid unnecessary re-renders - // Based on: https://reactjs.org/docs/hooks-faq.html#can-i-run-an-effect-only-on-updates - if (isInitialMount.current) { - isInitialMount.current = false - } else { - reset(Object.assign({}, defaultDefaultValues, query)) - } - }, [reset, query]) - const sortedCountries = localisedCountries(intl.locale) .sort((a,b) => new Intl.Collator(intl.locale).compare(a.localisedCountryName, b.localisedCountryName)) const testNameValue = watch('test_name') - const showWebConnectivityFilters = isValidFilterForTestname(testNameValue, testsWithValidDomainFilter) + const countryValue = watch('probe_cc') + const showWebConnectivityFilters = useMemo(() => (isValidFilterForTestname(testNameValue, testsWithValidDomainFilter)), [testNameValue]) // reset domain and input when web_connectivity is deselected - useLayoutEffect(() => { - setValue('domain', '') - setValue('input', '') + useEffect(() => { + if (!showWebConnectivityFilters) { + setValue('domain', '') + setValue('input', '') + } }, [setValue, showWebConnectivityFilters]) const [showDatePicker, setShowDatePicker] = useState(false) @@ -170,6 +169,22 @@ export const Form = ({ onSubmit, testNames, query }) => { } }, [getValues, onConfirm]) + const xAxisOptionsFiltered = useMemo(() => { + return filterAxisOptions(xAxisOptions, countryValue, testNameValue) + }, [testNameValue, countryValue]) + + useEffect(() => { + if (!xAxisOptionsFiltered.includes(getValues('axis_x'))) setValue('axis_x', 'measurement_start_day') + }, [setValue, getValues, xAxisOptionsFiltered]) + + const yAxisOptionsFiltered = useMemo(() => { + return filterAxisOptions(yAxisOptions, countryValue, testNameValue) + }, [testNameValue, countryValue]) + + useEffect(() => { + if (!yAxisOptionsFiltered.includes(getValues('axis_y'))) setValue('axis_y', '') + }, [setValue, getValues, yAxisOptionsFiltered]) + return (
@@ -259,7 +274,7 @@ export const Form = ({ onSubmit, testNames, query }) => { control={control} render={({field}) => ( @@ -275,7 +290,7 @@ export const Form = ({ onSubmit, testNames, query }) => { control={control} render={({field}) => ( diff --git a/pages/_app.js b/pages/_app.js index ef3425645..05eeb51c9 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -3,7 +3,7 @@ // https://github.com/vercel/next.js/blob/canary/examples/with-loading/pages/_app.js import 'scripts/wdyr' import 'regenerator-runtime/runtime' -import { useEffect, useId, useMemo, useState } from 'react' +import { useEffect } from 'react' import 'regenerator-runtime/runtime' import NProgress from 'nprogress' import { useRouter } from 'next/router' diff --git a/public/static/lang/en.json b/public/static/lang/en.json index 2a5f0d6f0..651a5b61b 100644 --- a/public/static/lang/en.json +++ b/public/static/lang/en.json @@ -462,8 +462,8 @@ "MAT.SubTitle": "Create charts based on aggregate views of real-time OONI data from around the world", "MAT.JSONData": "JSON Data", "MAT.CSVData": "CSV Data", - "MAT.Form.Label.XAxis": "X Axis", - "MAT.Form.Label.YAxis": "Y Axis", + "MAT.Form.Label.XAxis": "Columns", + "MAT.Form.Label.YAxis": "Rows", "MAT.Form.Label.AxisOption.domain": "Domain", "MAT.Form.Label.AxisOption.input": "Input", "MAT.Form.Label.AxisOption.measurement_start_day": "Measurement Day", @@ -496,7 +496,7 @@ "MAT.Charts.NoData.Details": "Details:", "MAT.Help.Box.Title": "Help", "MAT.Help.Title": "FAQs", - "MAT.Help.Content": "# What is the MAT?\n\nOONI's Measurement Aggregation Toolkit (MAT) is a tool that enables you to generate your own custom charts based on **aggregate views of real-time OONI data** collected from around the world.\n\nOONI data consists of network measurements collected by [OONI Probe](https://ooni.org/install/) users around the world. \n\nThese measurements contain information about various types of **internet censorship**, such as the [blocking of websites and apps](https://ooni.org/nettest/) around the world. \n\n# Who is the MAT for?\n\nThe MAT was built for researchers, journalists, and human rights defenders interested in examining internet censorship around the world.\n\n# Why use the MAT?\n\nWhen examining cases of internet censorship, it's important to **look at many measurements at once** (\"in aggregate\") in order to answer key questions like the following:\n\n* Does the testing of a service (e.g. Facebook) present **signs of blocking every time that it is tested** in a country? This can be helpful for ruling out [false positives](https://ooni.org/support/faq/#what-are-false-positives).\n* What types of websites (e.g. human rights websites) are blocked in each country?\n* In which countries is a specific website (e.g. `bbc.com`) blocked?\n* How does the blocking of different apps (e.g. WhatsApp or Telegram) vary across countries?\n* How does the blocking of a service vary across countries and [ASNs](https://ooni.org/support/glossary/#asn)?\n* How does the blocking of a service change over time?\n\nWhen trying to answer questions like the above, we normally perform relevant data analysis (instead of inspecting measurements one by one). \n\nThe MAT incorporates our data analysis techniques, enabling you to answer such questions without any data analysis skills, and with the click of a button!\n\n# How to use the MAT?\n\nThrough the filters at the start of the page, select the parameters you care about in order to plot charts based on aggregate views of OONI data.\n\nThe MAT includes the following filters:\n\n* **Countries:** Select a country through the drop-down menu (the \"All Countries\" option will show global coverage)\n* **Test Name:** Select an [OONI Probe test](https://ooni.org/nettest/) based on which you would like to get measurements (for example, select `Web Connectivity` to view the testing of websites)\n* **Domain:** Type the domain for the website you would like to get measurements (e.g. `twitter.com`)\n* **Website categories:** Select the [website category](https://github.com/citizenlab/test-lists/blob/master/lists/00-LEGEND-new_category_codes.csv) for which you would like to get measurements (e.g. `News Media` for news media websites)\n* **ASN:** Type the [ASN](https://ooni.org/support/glossary/#asn) of the network for which you would like to get measurements (e.g. `AS30722` for Vodafone Italia)\n* **Date range:** Select the date range of the measurements by adjusting the `Since` and `Until` filters\n* **X axis:** Select the values that you would like to appear on the horizontal axis of your chart\n* **Y axis:** Select the values that you would like to appear on the vertical axis of your chart\n\nDepending on what you would like to explore, adjust the MAT filters accordingly and click `Show Chart`. \n\nFor example, if you would like to check the testing of BBC in all countries around the world:\n\n* Type `www.bbc.com` under `Domain`\n* Select `Countries` under the `Y axis`\n* Click `Show Chart`\n\nThis will plot numerous charts based on the OONI Probe testing of `www.bbc.com` worldwide.\n\n# Interpreting MAT charts\n\nThe MAT charts (and associated tables) include the following values:\n\n* **OK count:** Successful measurements (i.e. NO sign of internet censorship)\n* **Confirmed count:** Measurements from automatically **confirmed blocked websites** (e.g. a [block page](https://ooni.org/support/glossary/#block-page) was served)\n* **Anomaly count:** Measurements that provided **signs of potential blocking** (however, [false positives](https://ooni.org/support/faq/#what-are-false-positives) can occur) \n* **Failure count:** Failed experiments that should be discarded\n* **Measurement count:** Total volume of OONI measurements (pertaining to the selected country, resource, etc.)\n\nWhen trying to identify the blocking of a service (e.g. `twitter.com`), it's useful to check whether:\n\n* Measurements are annotated as `confirmed`, automatically confirming the blocking of websites\n* A large volume of measurements (in comparison to the overall measurement count) present `anomalies` (i.e. signs of potential censorship)\n\nYou can access the raw data by clicking on the bars of charts, and subsequently clicking on the relevant measurement links. \n\n# Website categories\n\n[OONI Probe](https://ooni.org/install/) users test a wide range of [websites](https://ooni.org/support/faq/#which-websites-will-i-test-for-censorship-with-ooni-probe) that fall under the following [30 standardized categories](https://github.com/citizenlab/test-lists/blob/master/lists/00-LEGEND-new_category_codes.csv).", + "MAT.Help.Content": "# What is the MAT?\n\nOONI's Measurement Aggregation Toolkit (MAT) is a tool that enables you to generate your own custom charts based on **aggregate views of real-time OONI data** collected from around the world.\n\nOONI data consists of network measurements collected by [OONI Probe](https://ooni.org/install/) users around the world. \n\nThese measurements contain information about various types of **internet censorship**, such as the [blocking of websites and apps](https://ooni.org/nettest/) around the world. \n\n# Who is the MAT for?\n\nThe MAT was built for researchers, journalists, and human rights defenders interested in examining internet censorship around the world.\n\n# Why use the MAT?\n\nWhen examining cases of internet censorship, it's important to **look at many measurements at once** (\"in aggregate\") in order to answer key questions like the following:\n\n* Does the testing of a service (e.g. Facebook) present **signs of blocking every time that it is tested** in a country? This can be helpful for ruling out [false positives](https://ooni.org/support/faq/#what-are-false-positives).\n* What types of websites (e.g. human rights websites) are blocked in each country?\n* In which countries is a specific website (e.g. `bbc.com`) blocked?\n* How does the blocking of different apps (e.g. WhatsApp or Telegram) vary across countries?\n* How does the blocking of a service vary across countries and [ASNs](https://ooni.org/support/glossary/#asn)?\n* How does the blocking of a service change over time?\n\nWhen trying to answer questions like the above, we normally perform relevant data analysis (instead of inspecting measurements one by one). \n\nThe MAT incorporates our data analysis techniques, enabling you to answer such questions without any data analysis skills, and with the click of a button!\n\n# How to use the MAT?\n\nThrough the filters at the start of the page, select the parameters you care about in order to plot charts based on aggregate views of OONI data.\n\nThe MAT includes the following filters:\n\n* **Countries:** Select a country through the drop-down menu (the \"All Countries\" option will show global coverage)\n* **Test Name:** Select an [OONI Probe test](https://ooni.org/nettest/) based on which you would like to get measurements (for example, select `Web Connectivity` to view the testing of websites)\n* **Domain:** Type the domain for the website you would like to get measurements (e.g. `twitter.com`)\n* **Website categories:** Select the [website category](https://github.com/citizenlab/test-lists/blob/master/lists/00-LEGEND-new_category_codes.csv) for which you would like to get measurements (e.g. `News Media` for news media websites)\n* **ASN:** Type the [ASN](https://ooni.org/support/glossary/#asn) of the network for which you would like to get measurements (e.g. `AS30722` for Vodafone Italia)\n* **Date range:** Select the date range of the measurements by adjusting the `Since` and `Until` filters\n* **Columns:** Select the values that you would like to appear on the horizontal axis of your chart\n* **Rows:** Select the values that you would like to appear on the vertical axis of your chart\n\nDepending on what you would like to explore, adjust the MAT filters accordingly and click `Show Chart`. \n\nFor example, if you would like to check the testing of BBC in all countries around the world:\n\n* Type `www.bbc.com` under `Domain`\n* Select `Countries` under the `Rows`\n* Click `Show Chart`\n\nThis will plot numerous charts based on the OONI Probe testing of `www.bbc.com` worldwide.\n\n# Interpreting MAT charts\n\nThe MAT charts (and associated tables) include the following values:\n\n* **OK count:** Successful measurements (i.e. NO sign of internet censorship)\n* **Confirmed count:** Measurements from automatically **confirmed blocked websites** (e.g. a [block page](https://ooni.org/support/glossary/#block-page) was served)\n* **Anomaly count:** Measurements that provided **signs of potential blocking** (however, [false positives](https://ooni.org/support/faq/#what-are-false-positives) can occur) \n* **Failure count:** Failed experiments that should be discarded\n* **Measurement count:** Total volume of OONI measurements (pertaining to the selected country, resource, etc.)\n\nWhen trying to identify the blocking of a service (e.g. `twitter.com`), it's useful to check whether:\n\n* Measurements are annotated as `confirmed`, automatically confirming the blocking of websites\n* A large volume of measurements (in comparison to the overall measurement count) present `anomalies` (i.e. signs of potential censorship)\n\nYou can access the raw data by clicking on the bars of charts, and subsequently clicking on the relevant measurement links. \n\n# Website categories\n\n[OONI Probe](https://ooni.org/install/) users test a wide range of [websites](https://ooni.org/support/faq/#which-websites-will-i-test-for-censorship-with-ooni-probe) that fall under the following [30 standardized categories](https://github.com/citizenlab/test-lists/blob/master/lists/00-LEGEND-new_category_codes.csv).", "MAT.Help.Subtitle.Categories": "Categories", "MAT.CustomTooltip.ViewMeasurements": "View measurements", "ReachabilityDash.Heading.CircumventionTools": "Reachability of Censorship Circumvention Tools",