11import { BeakerIcon , BookOpenIcon } from "@heroicons/react/24/solid" ;
22import { type MetaFunction , useNavigation , useRevalidator } from "@remix-run/react" ;
33import { type LoaderFunctionArgs } from "@remix-run/server-runtime" ;
4- import { Suspense } from "react" ;
4+ import { Suspense , useEffect , useState } from "react" ;
55import {
66 TypedAwait ,
77 typeddefer ,
@@ -26,6 +26,7 @@ import {
2626 ResizablePanel ,
2727 ResizablePanelGroup ,
2828 collapsibleHandleClassName ,
29+ useFrozenValue ,
2930} from "~/components/primitives/Resizable" ;
3031import { SelectedItemsProvider } from "~/components/primitives/SelectedItemsProvider" ;
3132import { ShortcutKey } from "~/components/primitives/ShortcutKey" ;
@@ -39,6 +40,7 @@ import { $replica } from "~/db.server";
3940import { useEnvironment } from "~/hooks/useEnvironment" ;
4041import { useOrganization } from "~/hooks/useOrganizations" ;
4142import { useProject } from "~/hooks/useProject" ;
43+ import { useOptimisticLocation } from "~/hooks/useOptimisticLocation" ;
4244import { useSearchParams } from "~/hooks/useSearchParam" ;
4345import { useShortcutKeys } from "~/hooks/useShortcutKeys" ;
4446import { redirectWithErrorMessage } from "~/models/message.server" ;
@@ -56,7 +58,6 @@ import { cn } from "~/utils/cn";
5658import {
5759 docsPath ,
5860 EnvironmentParamSchema ,
59- v3CreateBulkActionPath ,
6061 v3ProjectPath ,
6162 v3TestPath ,
6263 v3TestTaskPath ,
@@ -65,8 +66,11 @@ import { throwNotFound } from "~/utils/httpErrors";
6566import { ListPagination } from "../../components/ListPagination" ;
6667import { CreateBulkActionInspector } from "../resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.bulkaction" ;
6768import { Callout } from "~/components/primitives/Callout" ;
69+ import { isRunsListLoading , shouldRevalidateRunsList } from "./shouldRevalidateRunsList" ;
6870import { useRunsLiveReload } from "./useRunsLiveReload" ;
6971
72+ export { shouldRevalidateRunsList as shouldRevalidate } ;
73+
7074export const meta : MetaFunction = ( ) => {
7175 return [
7276 {
@@ -209,8 +213,9 @@ function RunsList({
209213 filters : TaskRunListSearchFilters ;
210214} ) {
211215 const revalidator = useRevalidator ( ) ;
216+ const location = useOptimisticLocation ( ) ;
212217 const navigation = useNavigation ( ) ;
213- const isLoading = navigation . state !== "idle" ;
218+ const isLoading = isRunsListLoading ( navigation , location . search ) ;
214219 const organization = useOrganization ( ) ;
215220 const project = useProject ( ) ;
216221 const environment = useEnvironment ( ) ;
@@ -244,7 +249,7 @@ function RunsList({
244249 shortcut : { key : "r" } ,
245250 action : ( e ) => {
246251 replace ( {
247- bulkInspector : "true " ,
252+ bulkInspector : "show " ,
248253 action : "replay" ,
249254 mode : selectedItems . size > 0 ? "selected" : undefined ,
250255 } ) ;
@@ -254,14 +259,28 @@ function RunsList({
254259 shortcut : { key : "c" } ,
255260 action : ( e ) => {
256261 replace ( {
257- bulkInspector : "true " ,
262+ bulkInspector : "show " ,
258263 action : "cancel" ,
259264 mode : selectedItems . size > 0 ? "selected" : undefined ,
260265 } ) ;
261266 } ,
262267 } ) ;
263268
264269 const isShowingBulkActionInspector = has ( "bulkInspector" ) && list . hasAnyRuns ;
270+ const [ isBulkInspectorPanelCollapsed , setIsBulkInspectorPanelCollapsed ] = useState (
271+ ! isShowingBulkActionInspector
272+ ) ;
273+ const frozenShowBulkInspector = useFrozenValue ( isShowingBulkActionInspector || undefined ) ;
274+ const showBulkInspectorContent =
275+ isShowingBulkActionInspector ||
276+ ( frozenShowBulkInspector === true && ! isBulkInspectorPanelCollapsed ) ;
277+
278+ useEffect ( ( ) => {
279+ if ( isShowingBulkActionInspector ) {
280+ setIsBulkInspectorPanelCollapsed ( false ) ;
281+ }
282+ } , [ isShowingBulkActionInspector ] ) ;
283+
265284 return (
266285 < ResizablePanelGroup orientation = "horizontal" className = "max-h-full" >
267286 < ResizablePanel id = "runs-main" min = { "100px" } >
@@ -310,39 +329,39 @@ function RunsList({
310329 </ Button >
311330 </ span >
312331 ) }
313- { ! isShowingBulkActionInspector && (
314- < LinkButton
315- variant = "secondary/small"
316- to = { v3CreateBulkActionPath (
317- organization ,
318- project ,
319- environment ,
320- filters ,
321- selectedItems . size > 0 ? "selected" : undefined
322- ) }
323- LeadingIcon = { ListCheckedIcon }
324- className = { selectedItems . size > 0 ? "pr-1" : undefined }
325- tooltip = {
326- < div className = "-mr-1 flex items-center gap-3 text-xs text-text-dimmed" >
327- < div className = "flex items-center gap-0.5" >
328- < span > Replay</ span >
329- < ShortcutKey shortcut = { { key : "r" } } variant = { "small" } />
330- </ div >
331- < div className = "flex items-center gap-0.5" >
332- < span > Cancel</ span >
333- < ShortcutKey shortcut = { { key : "c" } } variant = { "small" } />
334- </ div >
332+ < Button
333+ variant = "secondary/small"
334+ onClick = { ( ) =>
335+ replace ( {
336+ bulkInspector : "show" ,
337+ mode : selectedItems . size > 0 ? "selected" : undefined ,
338+ } )
339+ }
340+ LeadingIcon = { ListCheckedIcon }
341+ className = { cn (
342+ selectedItems . size > 0 ? "pr-1" : undefined ,
343+ isShowingBulkActionInspector && "pointer-events-none invisible"
344+ ) }
345+ tooltip = {
346+ < div className = "-mr-1 flex items-center gap-3 text-xs text-text-dimmed" >
347+ < div className = "flex items-center gap-0.5" >
348+ < span > Replay</ span >
349+ < ShortcutKey shortcut = { { key : "r" } } variant = { "small" } />
335350 </ div >
336- }
337- >
338- < span className = "flex items-center gap-x-1 whitespace-nowrap text-text-bright" >
339- < span > Bulk action</ span >
340- { selectedItems . size > 0 && (
341- < Badge variant = "rounded" > { selectedItems . size } </ Badge >
342- ) }
343- </ span >
344- </ LinkButton >
345- ) }
351+ < div className = "flex items-center gap-0.5" >
352+ < span > Cancel</ span >
353+ < ShortcutKey shortcut = { { key : "c" } } variant = { "small" } />
354+ </ div >
355+ </ div >
356+ }
357+ >
358+ < span className = "flex items-center gap-x-1 whitespace-nowrap text-text-bright" >
359+ < span > Bulk action</ span >
360+ { selectedItems . size > 0 && (
361+ < Badge variant = "rounded" > { selectedItems . size } </ Badge >
362+ ) }
363+ </ span >
364+ </ Button >
346365 < ListPagination list = { list } />
347366 </ div >
348367 </ div >
@@ -374,12 +393,12 @@ function RunsList({
374393 className = "overflow-hidden"
375394 collapsible
376395 collapsed = { ! isShowingBulkActionInspector }
377- onCollapseChange = { ( ) => { } }
396+ onCollapseChange = { setIsBulkInspectorPanelCollapsed }
378397 collapsedSize = "0px"
379398 collapseAnimation = { RESIZABLE_PANEL_ANIMATION }
380399 >
381400 < div className = "h-full" style = { { minWidth : 400 } } >
382- { isShowingBulkActionInspector && (
401+ { showBulkInspectorContent && (
383402 < CreateBulkActionInspector
384403 filters = { filters }
385404 selectedItems = { selectedItems }
0 commit comments