Skip to content

Commit

Permalink
Merge pull request #2415 from target/wouter
Browse files Browse the repository at this point in the history
ui: migrate from react-router to wouter
  • Loading branch information
mastercactapus authored May 31, 2022
2 parents b3ab70a + 6c30bd4 commit 7a91ecf
Show file tree
Hide file tree
Showing 72 changed files with 1,121 additions and 1,395 deletions.
11 changes: 2 additions & 9 deletions web/src/app/actions/hooks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,10 @@ interface GetParamTest {

describe('getParamValues', () => {
function check(x: GetParamTest): void {
const defaultSearch = 'a=str&b=3&c=1&d=0&e=e&e=e&e=ee&f=ok%2Cgo%21'
const mockLocationObject = {
key: '',
search: x.search ? x.search : defaultSearch,
pathname: '',
state: '',
hash: '',
}
const search = x.search || 'a=str&b=3&c=1&d=0&e=e&e=e&e=ee&f=ok%2Cgo%21'

it(x.desc, () => {
expect(getParamValues(mockLocationObject, x.params)).toEqual(x.expected)
expect(getParamValues(search, x.params)).toEqual(x.expected)
})
}

Expand Down
50 changes: 30 additions & 20 deletions web/src/app/actions/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { Location } from 'history'
import { useNavigate, useLocation, NavigateFunction } from 'react-router-dom'
import { useLocation } from 'wouter'

export type Value = string | boolean | number | string[]

export function useURLKey(): string {
const [path] = useLocation()
return path + location.search
}

// sanitizeURLParam serializes a value to be ready to store in a URL.
// If a value cannot or should not be stored, an empty string is returned.
export function sanitizeURLParam(value: Value): string | string[] {
Expand All @@ -28,11 +32,11 @@ export function sanitizeURLParam(value: Value): string | string[] {
// getParamValues converts each URL search param into the
// desired type based on its respective default value.
export function getParamValues<T extends Record<string, Value>>(
location: Location,
search: string,
params: T, // <name, default> pairs
): T {
const result = {} as Record<string, Value>
const q = new URLSearchParams(location.search)
const q = new URLSearchParams(search)

for (const [name, defaultVal] of Object.entries(params)) {
if (!q.has(name)) {
Expand All @@ -52,21 +56,17 @@ export function getParamValues<T extends Record<string, Value>>(
return result as T
}

// setURLParams will replace the latest browser history entry with the provided params.
function setURLParams(
navigate: NavigateFunction,
location: Location,
params: URLSearchParams,
): void {
// newSearch will return a normalized URL search string if different from the current one.
function newSearch(params: URLSearchParams): [boolean, string] {
if (params.sort) params.sort()
let newSearch = params.toString()
newSearch = newSearch ? '?' + newSearch : ''

if (newSearch === location.search) {
// no action for no param change
return
return [false, '']
}
navigate(location.pathname + newSearch + location.hash, { replace: true })

return [true, newSearch]
}

// useURLParams returns the values for the given URL params if present, else the given defaults.
Expand All @@ -76,8 +76,7 @@ function setURLParams(
export function useURLParams<T extends Record<string, Value>>(
params: T, // <name, default> pairs
): [T, (newValues: Partial<T>) => void] {
const location = useLocation()
const navigate = useNavigate()
const [path, navigate] = useLocation()
const q = new URLSearchParams(location.search)
let called = false

Expand All @@ -102,10 +101,16 @@ export function useURLParams<T extends Record<string, Value>>(
}
}

setURLParams(navigate, location, q)
const [hasNew, search] = newSearch(q)
if (!hasNew) {
// nothing to do
return
}

navigate(path + search + location.hash, { replace: true })
}

const values = getParamValues<T>(location, params)
const values = getParamValues<T>(location.search, params)

return [values, setParams]
}
Expand All @@ -129,8 +134,7 @@ export function useURLParam<T extends Value>(
// The native history stack will not push a new entry; instead, its
// latest entry will be replaced.
export function useResetURLParams(...names: string[]): () => void {
const location = useLocation()
const navigate = useNavigate()
const [path, navigate] = useLocation()
let called = false

return function resetURLParams(): void {
Expand All @@ -150,6 +154,12 @@ export function useResetURLParams(...names: string[]): () => void {
const params = new URLSearchParams(location.search)
names.forEach((name) => params.delete(name))

setURLParams(navigate, location, params)
const [hasNew, search] = newSearch(params)
if (!hasNew) {
// nothing to do
return
}

navigate(path + search + location.hash, { replace: true })
}
}
32 changes: 0 additions & 32 deletions web/src/app/admin/AdminRouter.tsx

This file was deleted.

16 changes: 0 additions & 16 deletions web/src/app/alerts/AlertRouter.js

This file was deleted.

2 changes: 1 addition & 1 deletion web/src/app/alerts/AlertsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ export default function AlertsList(props) {
}
/>
),
url: `/alerts/${a.id}`,
url: `/services/${a.service.id}/alerts/${a.id}`,
selectable: a.status !== 'StatusClosed',
})}
variables={variables}
Expand Down
4 changes: 1 addition & 3 deletions web/src/app/alerts/pages/AlertDetailPage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react'
import { gql, useQuery } from '@apollo/client'
import { useParams } from 'react-router-dom'
import { GenericError, ObjectNotFound } from '../../error-pages'
import Spinner from '../../loading/components/Spinner'
import AlertDetails from '../components/AlertDetails'
Expand Down Expand Up @@ -42,8 +41,7 @@ const query = gql`
}
`

function AlertDetailPage() {
const { alertID } = useParams()
function AlertDetailPage({ alertID }) {
const { loading, error, data } = useQuery(query, {
variables: { id: alertID },
})
Expand Down
2 changes: 1 addition & 1 deletion web/src/app/documentation/Documentation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const useStyles = makeStyles({
},
})

export default function IntegrationKeyAPI(): JSX.Element {
export default function Documentation(): JSX.Element {
const [publicURL, webhookEnabled] = useConfigValue(
'General.PublicURL',
'Webhook.Enable',
Expand Down
4 changes: 2 additions & 2 deletions web/src/app/escalation-policies/PolicyCreateDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React, { useState } from 'react'
import { gql, useMutation } from '@apollo/client'
import p from 'prop-types'
import { fieldErrors, nonFieldErrors } from '../util/errutil'
import { Navigate } from 'react-router-dom'
import FormDialog from '../dialogs/FormDialog'
import PolicyForm from './PolicyForm'
import { Redirect } from 'wouter'

const mutation = gql`
mutation ($input: CreateEscalationPolicyInput!) {
Expand Down Expand Up @@ -38,7 +38,7 @@ function PolicyCreateDialog(props) {

if (data && data.createEscalationPolicy) {
return (
<Navigate to={`/escalation-policies/${data.createEscalationPolicy.id}`} />
<Redirect to={`/escalation-policies/${data.createEscalationPolicy.id}`} />
)
}

Expand Down
4 changes: 2 additions & 2 deletions web/src/app/escalation-policies/PolicyDeleteDialog.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react'
import { useMutation, gql } from '@apollo/client'
import p from 'prop-types'
import { useNavigate } from 'react-router-dom'
import FormDialog from '../dialogs/FormDialog'
import { useLocation } from 'wouter'

const mutation = gql`
mutation ($input: [TargetInput!]!) {
Expand All @@ -11,7 +11,7 @@ const mutation = gql`
`

export default function PolicyDeleteDialog(props) {
const navigate = useNavigate()
const [, navigate] = useLocation()
const [deletePolicy, deletePolicyStatus] = useMutation(mutation, {
variables: {
input: [
Expand Down
9 changes: 4 additions & 5 deletions web/src/app/escalation-policies/PolicyDetails.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useState } from 'react'
import { useQuery, gql } from '@apollo/client'
import { Navigate, useParams } from 'react-router-dom'
import _ from 'lodash'
import { Edit, Delete } from '@mui/icons-material'

Expand All @@ -15,6 +14,7 @@ import { useResetURLParams, useURLParam } from '../actions'
import { GenericError, ObjectNotFound } from '../error-pages'
import Spinner from '../loading/components/Spinner'
import { EPAvatar } from '../util/avatars'
import { Redirect } from 'wouter'

const query = gql`
query ($id: ID!) {
Expand All @@ -32,8 +32,7 @@ const query = gql`
}
`

export default function PolicyDetails() {
const { escalationPolicyID } = useParams()
export default function PolicyDetails({ policyID }) {
const stepNumParam = 'createStep'
const [createStep, setCreateStep] = useURLParam(stepNumParam, false)
const resetCreateStep = useResetURLParams(stepNumParam)
Expand All @@ -47,7 +46,7 @@ export default function PolicyDetails() {
data: _data,
} = useQuery(query, {
variables: {
id: escalationPolicyID,
id: policyID,
},
})

Expand All @@ -58,7 +57,7 @@ export default function PolicyDetails() {

if (!data) {
return showDeleteDialog ? (
<Navigate to='/escalation-policies' />
<Redirect to='/escalation-policies' />
) : (
<ObjectNotFound />
)
Expand Down
38 changes: 38 additions & 0 deletions web/src/app/escalation-policies/PolicyList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react'
import { gql } from 'urql'
import SimpleListPage from '../lists/SimpleListPage'
import PolicyCreateDialog from './PolicyCreateDialog'

const query = gql`
query epsQuery($input: EscalationPolicySearchOptions) {
data: escalationPolicies(input: $input) {
nodes {
id
name
description
isFavorite
}
pageInfo {
hasNextPage
endCursor
}
}
}
`

export default function PolicyList(): JSX.Element {
return (
<SimpleListPage
query={query}
variables={{ input: { favoritesFirst: true } }}
mapDataNode={(n) => ({
title: n.name,
subText: n.description,
url: n.id,
isFavorite: n.isFavorite,
})}
createForm={<PolicyCreateDialog />}
createLabel='Escalation Policy'
/>
)
}
56 changes: 0 additions & 56 deletions web/src/app/escalation-policies/PolicyRouter.js

This file was deleted.

Loading

0 comments on commit 7a91ecf

Please sign in to comment.