Skip to content

Commit

Permalink
Install newest @tanstack/react-router (#4384)
Browse files Browse the repository at this point in the history
* Install @tanstack/react-router

* Fix with imported switch

* Refactor redirect to new search parser

* Deregister timeout in ComparisonInput

* Comment uses of window.location

* Fix with imported switch appearing in realtime dashboard

* Handle not found routes more gracefully
  • Loading branch information
apata committed Jul 24, 2024
1 parent 6ed4f3a commit 28cf3ff
Show file tree
Hide file tree
Showing 35 changed files with 609 additions and 477 deletions.
14 changes: 10 additions & 4 deletions assets/js/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import React from 'react';
import { createRoot } from 'react-dom/client';
import 'url-search-params-polyfill';

import Router from './dashboard/router'
import { RouterProvider } from '@tanstack/react-router';
import { createAppRouter } from './dashboard/router'
import ErrorBoundary from './dashboard/error-boundary'
import * as api from './dashboard/api'
import * as timer from './dashboard/util/realtime-update-timer'
Expand All @@ -22,13 +23,18 @@ if (container) {
api.setSharedLinkAuth(sharedLinkAuth)
}

filtersBackwardsCompatibilityRedirect()

try {
filtersBackwardsCompatibilityRedirect(window.location)
} catch (e) {
console.error('Error redirecting in a backwards compatible way', e)
}

const router = createAppRouter(site);
const app = (
<ErrorBoundary>
<SiteContextProvider site={site}>
<UserContextProvider role={container.dataset.currentUserRole} loggedIn={container.dataset.loggedIn === 'true'}>
<Router />
<RouterProvider router={router} />
</UserContextProvider>
</SiteContextProvider>
</ErrorBoundary>
Expand Down
85 changes: 51 additions & 34 deletions assets/js/dashboard/comparison-input.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { Fragment } from 'react'
import { withRouter } from 'react-router-dom'
import React, { Fragment, useState, useRef, useEffect } from 'react'
import { navigateToQuery } from './query'
import { useNavigate } from '@tanstack/react-router'
import { Menu, Transition } from '@headlessui/react'
import { ChevronDownIcon } from '@heroicons/react/20/solid'
import classNames from 'classnames'
Expand All @@ -21,40 +21,55 @@ const DEFAULT_COMPARISON_MODE = 'previous_period'

export const COMPARISON_DISABLED_PERIODS = ['realtime', 'all']

export const getStoredMatchDayOfWeek = function (domain) {
return storage.getItem(`comparison_match_day_of_week__${domain}`) || 'true'
const getMatchDayOfWeekStorageKey = (domain) => storage.getDomainScopedStorageKey('comparison_match_day_of_week', domain)

const storeMatchDayOfWeek = function (domain, matchDayOfWeek) {
storage.setItem(getMatchDayOfWeekStorageKey(domain), matchDayOfWeek.toString());
}

export const getStoredComparisonMode = function (domain) {
const mode = storage.getItem(`comparison_mode__${domain}`)
if (Object.keys(COMPARISON_MODES).includes(mode)) {
return mode
} else {
return null
export const getStoredMatchDayOfWeek = function (domain, fallbackValue) {
const storedValue = storage.getItem(getMatchDayOfWeekStorageKey(domain));
if (storedValue === 'true') {
return true;
}
if (storedValue === 'false') {
return false;
}
return fallbackValue;
}

const getComparisonModeStorageKey = (domain) => storage.getDomainScopedStorageKey('comparison_mode', domain)

export const getStoredComparisonMode = function (domain, fallbackValue) {
const storedValue = storage.getItem(getComparisonModeStorageKey(domain))
if (Object.keys(COMPARISON_MODES).includes(storedValue)) {
return storedValue
}

return fallbackValue
}

const storeComparisonMode = function (domain, mode) {
if (mode == "custom") return
storage.setItem(`comparison_mode__${domain}`, mode)
storage.setItem(getComparisonModeStorageKey(domain), mode)
}

export const isComparisonEnabled = function (mode) {
return mode && mode !== "off"
}

export const toggleComparisons = function (history, query, site) {
export const toggleComparisons = function (navigate, query, site) {
if (COMPARISON_DISABLED_PERIODS.includes(query.period)) return

if (isComparisonEnabled(query.comparison)) {
storeComparisonMode(site.domain, "off")
navigateToQuery(history, query, { comparison: "off" })
navigateToQuery(navigate, query, { comparison: "off" })
} else {
const storedMode = getStoredComparisonMode(site.domain)
const storedMode = getStoredComparisonMode(site.domain, null)
const newMode = isComparisonEnabled(storedMode) ? storedMode : DEFAULT_COMPARISON_MODE

storeComparisonMode(site.domain, newMode)
navigateToQuery(history, query, { comparison: newMode })
navigateToQuery(navigate, query, { comparison: newMode })
}
}

Expand Down Expand Up @@ -86,12 +101,13 @@ function ComparisonModeOption({ label, value, isCurrentlySelected, updateMode, s
)
}

function MatchDayOfWeekInput({ history }) {
function MatchDayOfWeekInput() {
const navigate = useNavigate();
const site = useSiteContext()
const { query } = useQueryContext()
const click = (matchDayOfWeek) => {
storage.setItem(`comparison_match_day_of_week__${site.domain}`, matchDayOfWeek.toString())
navigateToQuery(history, query, { match_day_of_week: matchDayOfWeek.toString() })
storeMatchDayOfWeek(site.domain, matchDayOfWeek)
navigateToQuery(navigate, query, { match_day_of_week: matchDayOfWeek })
}

const buttonClass = (hover, selected) =>
Expand All @@ -116,15 +132,28 @@ function MatchDayOfWeekInput({ history }) {
</>
}

const ComparisonInput = function ({ history }) {
function ComparisonInput() {
const { query } = useQueryContext();
const site = useSiteContext();
const navigate = useNavigate();
const calendar = useRef(null)

const [uiMode, setUiMode] = useState("menu")

useEffect(() => {
let timeout = null;
if (uiMode == "datepicker") {
timeout = setTimeout(() => calendar.current?.flatpickr.open(), 100)
}
return () => timeout && clearTimeout(timeout)
}, [uiMode])

if (COMPARISON_DISABLED_PERIODS.includes(query.period)) return null
if (!isComparisonEnabled(query.comparison)) return null

const updateMode = (mode, from = null, to = null) => {
storeComparisonMode(site.domain, mode)
navigateToQuery(history, query, { comparison: mode, compare_from: from, compare_to: to })
navigateToQuery(navigate, query, { comparison: mode, compare_from: from, compare_to: to })
}

const buildLabel = (site, query) => {
Expand All @@ -135,18 +164,6 @@ const ComparisonInput = function ({ history }) {
}
}

// eslint-disable-next-line react-hooks/rules-of-hooks
const calendar = React.useRef(null)

// eslint-disable-next-line react-hooks/rules-of-hooks
const [uiMode, setUiMode] = React.useState("menu")
// eslint-disable-next-line react-hooks/rules-of-hooks
React.useEffect(() => {
if (uiMode == "datepicker") {
setTimeout(() => calendar.current.flatpickr.open(), 100)
}
}, [uiMode])

const flatpickrOptions = {
mode: 'range',
showMonths: 1,
Expand Down Expand Up @@ -186,7 +203,7 @@ const ComparisonInput = function ({ history }) {
{Object.keys(COMPARISON_MODES).map((key) => ComparisonModeOption({ label: COMPARISON_MODES[key], value: key, isCurrentlySelected: key == query.comparison, updateMode, setUiMode }))}
{query.comparison !== "custom" && <span>
<hr className="my-1" />
<MatchDayOfWeekInput history={history} />
<MatchDayOfWeekInput />
</span>}
</Menu.Items>
</Transition>
Expand All @@ -202,4 +219,4 @@ const ComparisonInput = function ({ history }) {
)
}

export default withRouter(ComparisonInput)
export default ComparisonInput
51 changes: 26 additions & 25 deletions assets/js/dashboard/datepicker.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Fragment, useState, useEffect, useCallback, useRef } from "react";
import { withRouter } from "react-router-dom";
import { useNavigate } from "@tanstack/react-router";
import Flatpickr from "react-flatpickr";
import { ChevronDownIcon } from '@heroicons/react/20/solid';
import { Transition } from '@headlessui/react';
Expand Down Expand Up @@ -70,7 +70,7 @@ function renderArrow(query, site, period, prevDate, nextDate) {
return (
<div className={containerClass}>
<QueryButton
to={{ date: prevDate }}
search={{ date: prevDate }}
className={leftClass}
disabled={disabledLeft}
>
Expand All @@ -88,7 +88,7 @@ function renderArrow(query, site, period, prevDate, nextDate) {
</svg>
</QueryButton>
<QueryButton
to={{ date: nextDate }}
search={{ date: nextDate }}
className={rightClass}
disabled={disabledRight}
>
Expand Down Expand Up @@ -166,22 +166,23 @@ function DisplayPeriod() {
return 'Realtime'
}

function DatePicker({ history }) {
function DatePicker() {
const { query } = useQueryContext();
const site = useSiteContext();
const [open, setOpen] = useState(false)
const [mode, setMode] = useState('menu')
const dropDownNode = useRef(null)
const calendar = useRef(null)
const navigate = useNavigate();

const handleKeydown = useCallback((e) => {
if (shouldIgnoreKeypress(e)) return true

const newSearch = {
period: false,
from: false,
to: false,
date: false
period: null,
from: null,
to: null,
date: null
};

const insertionDate = parseUTCDate(site.statsBegin);
Expand Down Expand Up @@ -222,28 +223,28 @@ function DatePicker({ history }) {
setOpen(false);

const keybindings = {
d: { date: false, period: 'day' },
d: { date: null, period: 'day' },
e: { date: formatISO(shiftDays(nowForSite(site), -1)), period: 'day' },
r: { period: 'realtime' },
w: { date: false, period: '7d' },
m: { date: false, period: 'month' },
y: { date: false, period: 'year' },
t: { date: false, period: '30d' },
s: { date: false, period: '6mo' },
l: { date: false, period: '12mo' },
a: { date: false, period: 'all' },
w: { date: null, period: '7d' },
m: { date: null, period: 'month' },
y: { date: null, period: 'year' },
t: { date: null, period: '30d' },
s: { date: null, period: '6mo' },
l: { date: null, period: '12mo' },
a: { date: null, period: 'all' },
}

const redirect = keybindings[e.key.toLowerCase()]
if (redirect) {
navigateToQuery(history, query, { ...newSearch, ...redirect })
navigateToQuery(navigate, query, { ...newSearch, ...redirect, keybindHint: e.key.toUpperCase() })
} else if (e.key.toLowerCase() === 'x') {
toggleComparisons(history, query, site)
toggleComparisons(navigate, query, site)
} else if (e.key.toLowerCase() === 'c') {
setOpen(true)
setMode('calendar')
} else if (newSearch.date) {
navigateToQuery(history, query, newSearch);
navigateToQuery(navigate, query, newSearch);
}
}, [query])

Check warning on line 249 in assets/js/dashboard/datepicker.js

View workflow job for this annotation

GitHub Actions / Build and test

React Hook useCallback has missing dependencies: 'navigate' and 'site'. Either include them or remove the dependency array

Expand Down Expand Up @@ -274,9 +275,9 @@ function DatePicker({ history }) {
[from, to] = [parseNaiveDate(from), parseNaiveDate(to)]

if (from.isSame(to)) {
navigateToQuery(history, query, { period: 'day', date: formatISO(from), from: false, to: false })
navigateToQuery(navigate, query, { period: 'day', date: formatISO(from), from: null, to: null })
} else {
navigateToQuery(history, query, { period: 'custom', date: false, from: formatISO(from), to: formatISO(to) })
navigateToQuery(navigate, query, { period: 'custom', date: null, from: formatISO(from), to: formatISO(to) })
}
}

Expand Down Expand Up @@ -304,11 +305,11 @@ function DatePicker({ history }) {
boldClass = query.period === period ? "font-bold" : "";
}

opts.date = opts.date ? formatISO(opts.date) : false;
opts.date = opts.date ? formatISO(opts.date) : null;

return (
<QueryLink
to={{ from: false, to: false, period, ...opts }}
search={{ from: null, to: null, period, ...opts }}
onClick={() => setOpen(false)}
className={`${boldClass} px-4 py-2 text-sm leading-tight hover:bg-gray-100 hover:text-gray-900
dark:hover:bg-gray-900 dark:hover:text-gray-100 flex items-center justify-between`}
Expand Down Expand Up @@ -370,7 +371,7 @@ function DatePicker({ history }) {
<div className="py-1 date-option-group border-t border-gray-200 dark:border-gray-500">
<span
onClick={() => {
toggleComparisons(history, query, site)
toggleComparisons(navigate, query, site)
setOpen(false)
}}
className="px-4 py-2 text-sm leading-tight hover:bg-gray-100 dark:hover:bg-gray-900 hover:text-gray-900 dark:hover:text-gray-100 cursor-pointer flex items-center justify-between">
Expand Down Expand Up @@ -450,4 +451,4 @@ function DatePicker({ history }) {
)
}

export default withRouter(DatePicker);
export default DatePicker
Loading

0 comments on commit 28cf3ff

Please sign in to comment.