From c425be691d92fd50e25837acb395846efcb9e078 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Tue, 30 Jul 2024 06:13:31 +0200 Subject: [PATCH 1/9] feat: responsive sidebar --- assets/App.tsx | 8 +++-- assets/hooks/useBreakpoint.tsx | 19 ++++++++++++ package.json | 2 ++ yarn.lock | 57 ++++++++++++++++++++++++++++++++-- 4 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 assets/hooks/useBreakpoint.tsx diff --git a/assets/App.tsx b/assets/App.tsx index 7b89360..6b41d1b 100644 --- a/assets/App.tsx +++ b/assets/App.tsx @@ -32,6 +32,7 @@ import ConnectorsPage from "./pages/tracking/ConnectorsPage"; import NotFoundPage from "./pages/NotFoundPage"; import {ItemType, MenuItemType} from "antd/lib/menu/interface"; import {t} from 'ttag' +import useBreakpoint from "./hooks/useBreakpoint"; export default function App() { const { @@ -40,6 +41,7 @@ export default function App() { const navigate = useNavigate() const location = useLocation() + const sm = useBreakpoint('sm') const [isAuthenticated, setIsAuthenticated] = useState(false) @@ -184,7 +186,8 @@ export default function App() { return - + {/* Ant will use a break-off tab to toggle the collapse of the sider when collapseWidth = 0*/} + navigate('/login') }]} /> -
@@ -243,7 +245,7 @@ export default function App() { Domain - Watchdog ©{new Date().getFullYear()} Created by Maël Gangloff + Watchdog © {new Date().getFullYear()} Created by Maël Gangloff diff --git a/assets/hooks/useBreakpoint.tsx b/assets/hooks/useBreakpoint.tsx new file mode 100644 index 0000000..60e4168 --- /dev/null +++ b/assets/hooks/useBreakpoint.tsx @@ -0,0 +1,19 @@ +import { Breakpoint, theme } from 'antd'; +import { useMediaQuery } from 'react-responsive'; + +const { useToken } = theme; + +type ScreenProperty = 'screenXXL' | 'screenXL' | 'screenLG' | 'screenMD' | 'screenSM' | 'screenXS'; + +const propertyName = (breakpoint: Breakpoint): ScreenProperty => { + return 'screen' + breakpoint.toUpperCase() as ScreenProperty +}; + +export default function useBreakpoint( + breakpoint: Breakpoint +) { + const { token } = useToken() + const width: number = token[propertyName(breakpoint)] + + return useMediaQuery({maxWidth: width}) +} diff --git a/package.json b/package.json index 45fcf20..a83a175 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@types/punycode": "^2.1.4", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", + "@types/react-responsive": "^8.0.8", "@types/vcf": "^2.0.7", "antd": "^5.19.3", "axios": "^1.7.2", @@ -33,6 +34,7 @@ "punycode": "^2.3.1", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-responsive": "^10.0.0", "react-router-dom": "^6.25.1", "regenerator-runtime": "^0.13.9", "snarkdown": "^2.0.0", diff --git a/yarn.lock b/yarn.lock index 8057a0c..adc5b56 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1886,6 +1886,13 @@ dependencies: "@types/react" "*" +"@types/react-responsive@^8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@types/react-responsive/-/react-responsive-8.0.8.tgz#e351be7cc4d03bc476075839922bb5f9a3094e76" + integrity sha512-HDUZtoeFRHrShCGaND23HmXAB9evOOTjkghd2wAasLkuorYYitm5A1XLeKkhXKZppcMBxqB/8V4Snl6hRUTA8g== + dependencies: + "@types/react" "*" + "@types/react@*", "@types/react@^18.3.3": version "18.3.3" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f" @@ -2932,6 +2939,11 @@ css-loader@^6.7.0: postcss-value-parser "^4.2.0" semver "^7.5.4" +css-mediaquery@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/css-mediaquery/-/css-mediaquery-0.1.2.tgz#6a2c37344928618631c54bd33cedd301da18bea0" + integrity sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q== + css-minimizer-webpack-plugin@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz#33effe662edb1a0bf08ad633c32fa75d0f7ec565" @@ -4058,6 +4070,11 @@ hunspell-spellchecker@^1.0.2: resolved "https://registry.yarnpkg.com/hunspell-spellchecker/-/hunspell-spellchecker-1.0.2.tgz#a10b0bd2fa00a65ab62a4c6b734ce496d318910e" integrity sha512-4DwmFAvlz+ChsqLDsZT2cwBsYNXh+oWboemxXtafwKIyItq52xfR4e4kr017sLAoPaSYVofSOvPUfmOAhXyYvw== +hyphenate-style-name@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz#1797bf50369588b47b72ca6d5e65374607cf4436" + integrity sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw== + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -4624,7 +4641,7 @@ log-symbols@^1.0.2: dependencies: chalk "^1.0.0" -loose-envify@^1.1.0: +loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -4660,6 +4677,13 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +matchmediaquery@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/matchmediaquery/-/matchmediaquery-0.4.2.tgz#22582bd4ae63ad9f54c53001bba80cbed0f7eafa" + integrity sha512-wrZpoT50ehYOudhDjt/YvUJc6eUzcdFPdmbizfgvswCKNHD1/OBOHYJpHie+HXpu6bSkEGieFMYk6VuutaiRfA== + dependencies: + css-mediaquery "^0.1.2" + mdn-data@2.0.28: version "2.0.28" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" @@ -4882,7 +4906,7 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" -object-assign@^4.0.1: +object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -5461,6 +5485,15 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== +prop-types@^15.6.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -5886,11 +5919,26 @@ react-dom@^18.3.1: loose-envify "^1.1.0" scheduler "^0.23.2" +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + react-is@^18.2.0: version "18.3.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== +react-responsive@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/react-responsive/-/react-responsive-10.0.0.tgz#657c7a90823cd565f43aa5918bd8eb0cd2c91c91" + integrity sha512-N6/UiRLGQyGUqrarhBZmrSmHi2FXSD++N5VbSKsBBvWfG0ZV7asvUBluSv5lSzdMyEVjzZ6Y8DL4OHABiztDOg== + dependencies: + hyphenate-style-name "^1.0.0" + matchmediaquery "^0.4.2" + prop-types "^15.6.1" + shallow-equal "^3.1.0" + react-router-dom@^6.25.1: version "6.25.1" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.25.1.tgz#b89f8d63fc8383ea4e89c44bf31c5843e1f7afa0" @@ -6343,6 +6391,11 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" +shallow-equal@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-3.1.0.tgz#e7a54bac629c7f248eff6c2f5b63122ba4320bec" + integrity sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg== + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" From 84716708db6804d645f9c93eb7d262f921aba48e Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Tue, 30 Jul 2024 06:21:37 +0200 Subject: [PATCH 2/9] feat: no content margin on sm --- assets/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/App.tsx b/assets/App.tsx index 6b41d1b..19c07d9 100644 --- a/assets/App.tsx +++ b/assets/App.tsx @@ -209,7 +209,7 @@ export default function App() { - +
Date: Tue, 30 Jul 2024 06:28:00 +0200 Subject: [PATCH 3/9] feat: one-sided timeline on sm --- assets/components/search/EventTimeline.tsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/assets/components/search/EventTimeline.tsx b/assets/components/search/EventTimeline.tsx index d04a142..b6e87a3 100644 --- a/assets/components/search/EventTimeline.tsx +++ b/assets/components/search/EventTimeline.tsx @@ -10,8 +10,10 @@ import {Timeline} from "antd"; import React from "react"; import {Domain} from "../../utils/api"; import {t} from "ttag"; +import useBreakpoint from "../../hooks/useBreakpoint"; export function EventTimeline({domain}: { domain: Domain }) { + const sm = useBreakpoint('sm') const domainEvent = { registration: t`Registration`, @@ -30,7 +32,7 @@ export function EventTimeline({domain}: { domain: Domain }) { const locale = navigator.language.split('-')[0] return new Date(e2.date).getTime() - new Date(e1.date).getTime()) .map(({action, date}) => { @@ -56,12 +58,21 @@ export function EventTimeline({domain}: { domain: Domain }) { dot = } + const eventName = Object.keys(domainEvent).includes(action) ? domainEvent[action as keyof typeof domainEvent] : action + const dateStr = new Date(date).toLocaleString(locale) + + const text = sm ? { + children: <>{eventName} {dateStr} + } : { + label: dateStr, + children: eventName, + } + return { - label: new Date(date).toLocaleString(locale), - children: Object.keys(domainEvent).includes(action) ? domainEvent[action as keyof typeof domainEvent] : action, color, dot, - pending: new Date(date).getTime() > new Date().getTime() + pending: new Date(date).getTime() > new Date().getTime(), + ...text } } ) From 712293ee2bb82176feecfe4d45477739b7738750 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Tue, 30 Jul 2024 22:42:25 +0200 Subject: [PATCH 4/9] feat: domain handle in code style --- assets/pages/search/DomainSearchPage.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/pages/search/DomainSearchPage.tsx b/assets/pages/search/DomainSearchPage.tsx index 43526e2..b1d01c0 100644 --- a/assets/pages/search/DomainSearchPage.tsx +++ b/assets/pages/search/DomainSearchPage.tsx @@ -1,5 +1,5 @@ import React, {useState} from "react"; -import {Badge, Card, Divider, Empty, Flex, FormProps, message, Skeleton, Space, Tag} from "antd"; +import {Badge, Card, Divider, Empty, Flex, FormProps, message, Skeleton, Space, Tag, Typography} from "antd"; import {Domain, getDomain} from "../../utils/api"; import {AxiosError} from "axios" import {t} from 'ttag' @@ -7,6 +7,7 @@ import {DomainSearchBar, FieldType} from "../../components/search/DomainSearchBa import {EventTimeline} from "../../components/search/EventTimeline"; import {EntitiesList} from "../../components/search/EntitiesList"; +const { Text } = Typography; export default function DomainSearchPage() { const [domain, setDomain] = useState() @@ -40,7 +41,7 @@ export default function DomainSearchPage() { domain.tld.type === 'gTLD' ? "green" : "cyan" }> - {domain.ldhName}{domain.handle ? <> ({domain.handle}): undefined}} size="small"> {domain.status.length > 0 && <> From 34b4838a7260078bfe671a9c09483f9951f1f137 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Tue, 30 Jul 2024 23:32:22 +0200 Subject: [PATCH 5/9] feat: paginated and responsive TLD tables --- assets/pages/info/TldPage.tsx | 63 +++++++++++++++++++------------ config/packages/api_platform.yaml | 2 + public/manifest.json | 1 - 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/assets/pages/info/TldPage.tsx b/assets/pages/info/TldPage.tsx index 33e3585..94c4108 100644 --- a/assets/pages/info/TldPage.tsx +++ b/assets/pages/info/TldPage.tsx @@ -3,49 +3,65 @@ import {Collapse, Divider, Table, Typography} from "antd"; import {getTldList, Tld} from "../../utils/api"; import {t} from 'ttag' import {regionNames} from "../../i18n"; +import useBreakpoint from "../../hooks/useBreakpoint"; +import { ColumnType } from "antd/es/table"; const {Text, Paragraph} = Typography type TldType = 'iTLD' | 'sTLD' | 'gTLD' | 'ccTLD' type FiltersType = { type: TldType, contractTerminated?: boolean, specification13?: boolean } +const toEmoji = (tld: string) => { + if (tld.startsWith('xn--')) return '-' -const toEmoji = (tld: string) => String.fromCodePoint( - ...getCountryCode(tld) - .toUpperCase() - .split('') - .map((char) => 127397 + char.charCodeAt(0) - ) -) + return String.fromCodePoint( + ...getCountryCode(tld) + .toUpperCase() + .split('') + .map((char) => 127397 + char.charCodeAt(0)) + ) +} const getCountryCode = (tld: string): string => { const exceptions = {uk: 'gb', su: 'ru', tp: 'tl'} if (tld in exceptions) return exceptions[tld as keyof typeof exceptions] - return tld + return tld.toUpperCase() } function TldTable(filters: FiltersType) { + const sm = useBreakpoint('sm') const [dataTable, setDataTable] = useState([]) const [total, setTotal] = useState(0) - const fetchData = (params: FiltersType & { page: number }) => { + const fetchData = (params: FiltersType & { page: number, itemsPerPage: number }) => { getTldList(params).then((data) => { setTotal(data['hydra:totalItems']) setDataTable(data['hydra:member'].map((tld: Tld) => { switch (filters.type) { case 'ccTLD': + let countryName + + try { + countryName = regionNames.of(getCountryCode(tld.tld)) + } catch(e) { + countryName = '-' + } + return { + key: tld.tld, TLD: tld.tld, Flag: toEmoji(tld.tld), - Country: regionNames.of(getCountryCode(tld.tld)) ?? '-' + Country: countryName } case 'gTLD': return { + key: tld.tld, TLD: tld.tld, Operator: tld.registryOperator } default: return { + key: tld.tld, TLD: tld.tld } } @@ -54,31 +70,27 @@ function TldTable(filters: FiltersType) { } useEffect(() => { - fetchData({...filters, page: 1}) + fetchData({...filters, page: 1, itemsPerPage: 30}) }, []) - let columns = [ + let columns: ColumnType[] = [ { title: t`TLD`, - dataIndex: "TLD", - width: 20 + dataIndex: "TLD" } ] if (filters.type === 'ccTLD') columns = [...columns, { title: t`Flag`, dataIndex: "Flag", - width: 20 }, { title: t`Country`, - dataIndex: "Country", - width: 200 + dataIndex: "Country" }] if (filters.type === 'gTLD') columns = [...columns, { title: t`Registry Operator`, - dataIndex: "Operator", - width: 50 + dataIndex: "Operator" }] @@ -87,18 +99,21 @@ function TldTable(filters: FiltersType) { dataSource={dataTable} pagination={{ total, - pageSize: 30, hideOnSinglePage: true, - onChange: (page, pageSize) => { - fetchData({...filters, page}) + defaultPageSize: 30, + onChange: (page, itemsPerPage) => { + fetchData({...filters, page, itemsPerPage}) } }} - scroll={{y: 240}} + + {...(sm ? {scroll: {y: 'mex-content'}} : {scroll: {y: 240}})} /> } export default function TldPage() { + const sm = useBreakpoint('sm') + return <> {t`This page presents all active TLDs in the root zone database.`} @@ -111,7 +126,7 @@ export default function TldPage() { Date: Tue, 30 Jul 2024 23:32:50 +0200 Subject: [PATCH 6/9] fix: typo --- assets/pages/info/TldPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/pages/info/TldPage.tsx b/assets/pages/info/TldPage.tsx index 94c4108..5ae2a48 100644 --- a/assets/pages/info/TldPage.tsx +++ b/assets/pages/info/TldPage.tsx @@ -106,7 +106,7 @@ function TldTable(filters: FiltersType) { } }} - {...(sm ? {scroll: {y: 'mex-content'}} : {scroll: {y: 240}})} + {...(sm ? {scroll: {y: 'max-content'}} : {scroll: {y: 240}})} /> } From b713a1ae47a63c0ed9aa0b03ff990c7621fa4aa1 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Wed, 31 Jul 2024 02:10:55 +0200 Subject: [PATCH 7/9] feat: use Noto Emoji Color --- assets/index.css | 16 ++++++++++++++-- assets/index.tsx | 2 ++ package.json | 1 + yarn.lock | 5 +++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/assets/index.css b/assets/index.css index 4e41b69..2a5fa74 100644 --- a/assets/index.css +++ b/assets/index.css @@ -1,3 +1,15 @@ +@font-face { + font-family: "Noto Color Emoji"; + font-style: normal; + font-display: swap; + font-weight: 400; + src: url(@fontsource/noto-color-emoji/files/noto-color-emoji-emoji-400-normal.woff2) + format("woff2"), + url(@fontsource/noto-color-emoji/files/noto-color-emoji-emoji-400-normal.woff) + format("woff"); +} + body { - margin: 0; -} \ No newline at end of file + margin: 0; + font-family: "Noto Color Emoji", sans-serif; +} diff --git a/assets/index.tsx b/assets/index.tsx index 308a7e3..3659847 100644 --- a/assets/index.tsx +++ b/assets/index.tsx @@ -6,6 +6,8 @@ import {HashRouter} from "react-router-dom"; import 'antd/dist/reset.css'; import './i18n' +import './index.css' + const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement) diff --git a/package.json b/package.json index a83a175..b4d3eed 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@babel/core": "^7.17.0", "@babel/preset-env": "^7.16.0", "@babel/preset-react": "^7.24.7", + "@fontsource/noto-color-emoji": "^5.0.27", "@symfony/webpack-encore": "^4.0.0", "@types/axios": "^0.14.0", "@types/jsonld": "^1.5.15", diff --git a/yarn.lock b/yarn.lock index adc5b56..7a8b554 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1499,6 +1499,11 @@ resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== +"@fontsource/noto-color-emoji@^5.0.27": + version "5.0.27" + resolved "https://registry.yarnpkg.com/@fontsource/noto-color-emoji/-/noto-color-emoji-5.0.27.tgz#61e40657bea980553bde8fd2d566104bd2859ad6" + integrity sha512-gsIMN5o8qoRLrA+XyDNKKnMNpTbwpNbINisJqirLOLXl83arOV2sHRnNOkVht2gzUcImUxEUBGektp56G3Vj9w== + "@jest/schemas@^29.6.3": version "29.6.3" resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" From f623d21ff4175b12c471cfa8eab02f82a58d36f0 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Wed, 31 Jul 2024 02:22:36 +0200 Subject: [PATCH 8/9] fix: responsive connector select --- assets/components/tracking/WatchlistForm.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/assets/components/tracking/WatchlistForm.tsx b/assets/components/tracking/WatchlistForm.tsx index db9f2a0..965b5ee 100644 --- a/assets/components/tracking/WatchlistForm.tsx +++ b/assets/components/tracking/WatchlistForm.tsx @@ -209,10 +209,17 @@ export function WatchlistForm({form, connectors, onCreateWatchlist}: {