fix(dashboard): Use derived state in DataTable (#11487)
**What** - Uses derived state in DataTable, to prevent the state in the URL and component from going out of sync. - Introduces a way for RouteModals to restore URL params on close. Resolves CMRC-936
This commit is contained in:
committed by
GitHub
parent
51b0af193c
commit
c28ae573e5
@@ -0,0 +1,26 @@
|
||||
import { useMemo } from "react"
|
||||
import { Path, useLocation } from "react-router-dom"
|
||||
|
||||
/**
|
||||
* Checks if the current location has a restore_params property.
|
||||
* If it does, it will return a new path with the params added to it.
|
||||
* Otherwise, it will return the previous path.
|
||||
*
|
||||
* This is useful if the modal needs to return to the original path, with
|
||||
* the params that were present when the modal was opened.
|
||||
*/
|
||||
export const useStateAwareTo = (prev: string | Partial<Path>) => {
|
||||
const location = useLocation()
|
||||
|
||||
const to = useMemo(() => {
|
||||
const params = location.state?.restore_params
|
||||
|
||||
if (!params) {
|
||||
return prev
|
||||
}
|
||||
|
||||
return `${prev}?${params.toString()}`
|
||||
}, [location.state, prev])
|
||||
|
||||
return to
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Drawer, clx } from "@medusajs/ui"
|
||||
import { PropsWithChildren, useEffect, useState } from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { Path, useNavigate } from "react-router-dom"
|
||||
import { useStateAwareTo } from "../hooks/use-state-aware-to"
|
||||
import { RouteModalForm } from "../route-modal-form"
|
||||
import { RouteModalProvider } from "../route-modal-provider/route-provider"
|
||||
import { StackedModalProvider } from "../stacked-modal-provider"
|
||||
|
||||
type RouteDrawerProps = PropsWithChildren<{
|
||||
prev?: string
|
||||
prev?: string | Partial<Path>
|
||||
}>
|
||||
|
||||
const Root = ({ prev = "..", children }: RouteDrawerProps) => {
|
||||
@@ -14,6 +15,8 @@ const Root = ({ prev = "..", children }: RouteDrawerProps) => {
|
||||
const [open, setOpen] = useState(false)
|
||||
const [stackedModalOpen, onStackedModalOpen] = useState(false)
|
||||
|
||||
const to = useStateAwareTo(prev)
|
||||
|
||||
/**
|
||||
* Open the modal when the component mounts. This
|
||||
* ensures that the entry animation is played.
|
||||
@@ -30,7 +33,7 @@ const Root = ({ prev = "..", children }: RouteDrawerProps) => {
|
||||
const handleOpenChange = (open: boolean) => {
|
||||
if (!open) {
|
||||
document.body.style.pointerEvents = "auto"
|
||||
navigate(prev, { replace: true })
|
||||
navigate(to, { replace: true })
|
||||
return
|
||||
}
|
||||
|
||||
@@ -39,7 +42,7 @@ const Root = ({ prev = "..", children }: RouteDrawerProps) => {
|
||||
|
||||
return (
|
||||
<Drawer open={open} onOpenChange={handleOpenChange}>
|
||||
<RouteModalProvider prev={prev}>
|
||||
<RouteModalProvider prev={to}>
|
||||
<StackedModalProvider onOpenChange={onStackedModalOpen}>
|
||||
<Drawer.Content
|
||||
aria-describedby={undefined}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { FocusModal, clx } from "@medusajs/ui"
|
||||
import { PropsWithChildren, useEffect, useState } from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { Path, useNavigate } from "react-router-dom"
|
||||
import { useStateAwareTo } from "../hooks/use-state-aware-to"
|
||||
import { RouteModalForm } from "../route-modal-form"
|
||||
import { useRouteModal } from "../route-modal-provider"
|
||||
import { RouteModalProvider } from "../route-modal-provider/route-provider"
|
||||
import { StackedModalProvider } from "../stacked-modal-provider"
|
||||
|
||||
type RouteFocusModalProps = PropsWithChildren<{
|
||||
prev?: string
|
||||
prev?: string | Partial<Path>
|
||||
}>
|
||||
|
||||
const Root = ({ prev = "..", children }: RouteFocusModalProps) => {
|
||||
@@ -15,6 +16,8 @@ const Root = ({ prev = "..", children }: RouteFocusModalProps) => {
|
||||
const [open, setOpen] = useState(false)
|
||||
const [stackedModalOpen, onStackedModalOpen] = useState(false)
|
||||
|
||||
const to = useStateAwareTo(prev)
|
||||
|
||||
/**
|
||||
* Open the modal when the component mounts. This
|
||||
* ensures that the entry animation is played.
|
||||
@@ -31,7 +34,7 @@ const Root = ({ prev = "..", children }: RouteFocusModalProps) => {
|
||||
const handleOpenChange = (open: boolean) => {
|
||||
if (!open) {
|
||||
document.body.style.pointerEvents = "auto"
|
||||
navigate(prev, { replace: true })
|
||||
navigate(to, { replace: true })
|
||||
return
|
||||
}
|
||||
|
||||
@@ -40,7 +43,7 @@ const Root = ({ prev = "..", children }: RouteFocusModalProps) => {
|
||||
|
||||
return (
|
||||
<FocusModal open={open} onOpenChange={handleOpenChange}>
|
||||
<RouteModalProvider prev={prev}>
|
||||
<RouteModalProvider prev={to}>
|
||||
<StackedModalProvider onOpenChange={onStackedModalOpen}>
|
||||
<Content stackedModalOpen={stackedModalOpen}>{children}</Content>
|
||||
</StackedModalProvider>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { PropsWithChildren, useCallback, useMemo, useState } from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { Path, useNavigate } from "react-router-dom"
|
||||
import { RouteModalProviderContext } from "./route-modal-context"
|
||||
|
||||
type RouteModalProviderProps = PropsWithChildren<{
|
||||
prev: string
|
||||
prev: string | Partial<Path>
|
||||
}>
|
||||
|
||||
export const RouteModalProvider = ({
|
||||
|
||||
Reference in New Issue
Block a user