11import { BeakerIcon , BookOpenIcon } from "@heroicons/react/24/solid" ;
2- import { type MetaFunction , useNavigation } from "@remix-run/react" ;
2+ import { type MetaFunction , useNavigation , useRevalidator } from "@remix-run/react" ;
33import { type LoaderFunctionArgs } from "@remix-run/server-runtime" ;
44import { Suspense } from "react" ;
55import {
@@ -14,11 +14,12 @@ import { DevDisconnectedBanner, useDevPresence } from "~/components/DevPresence"
1414import { StepContentContainer } from "~/components/StepContentContainer" ;
1515import { MainCenteredContainer , PageBody } from "~/components/layout/AppLayout" ;
1616import { Badge } from "~/components/primitives/Badge" ;
17- import { LinkButton } from "~/components/primitives/Buttons" ;
17+ import { Button , LinkButton } from "~/components/primitives/Buttons" ;
1818import { Header1 } from "~/components/primitives/Headers" ;
1919import { InfoPanel } from "~/components/primitives/InfoPanel" ;
2020import { NavBar , PageAccessories , PageTitle } from "~/components/primitives/PageHeader" ;
2121import { Paragraph } from "~/components/primitives/Paragraph" ;
22+ import { PulsingDot } from "~/components/primitives/PulsingDot" ;
2223import {
2324 RESIZABLE_PANEL_ANIMATION ,
2425 ResizableHandle ,
@@ -64,6 +65,7 @@ import { throwNotFound } from "~/utils/httpErrors";
6465import { ListPagination } from "../../components/ListPagination" ;
6566import { CreateBulkActionInspector } from "../resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.bulkaction" ;
6667import { Callout } from "~/components/primitives/Callout" ;
68+ import { useRunsLiveReload } from "./useRunsLiveReload" ;
6769
6870export const meta : MetaFunction = ( ) => {
6971 return [
@@ -89,7 +91,10 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
8991
9092 const filters = await getRunFiltersFromRequest ( request ) ;
9193
92- const clickhouse = await clickhouseFactory . getClickhouseForOrganization ( project . organizationId , "standard" ) ;
94+ const clickhouse = await clickhouseFactory . getClickhouseForOrganization (
95+ project . organizationId ,
96+ "standard"
97+ ) ;
9398 const presenter = new NextRunListPresenter ( $replica , clickhouse ) ;
9499 const list = presenter . call ( project . organizationId , environment . id , {
95100 userId,
@@ -203,12 +208,36 @@ function RunsList({
203208 rootOnlyDefault : boolean ;
204209 filters : TaskRunListSearchFilters ;
205210} ) {
211+ const revalidator = useRevalidator ( ) ;
206212 const navigation = useNavigation ( ) ;
207213 const isLoading = navigation . state !== "idle" ;
208214 const organization = useOrganization ( ) ;
209215 const project = useProject ( ) ;
210216 const environment = useEnvironment ( ) ;
211217 const { has, replace } = useSearchParams ( ) ;
218+ const { visibleRuns, showNewRunsBanner, newRunsCount, dismissNewRuns, childrenStatusesBasePath } =
219+ useRunsLiveReload ( {
220+ runs : list . runs ,
221+ hasAnyRuns : list . hasAnyRuns ,
222+ isLoading,
223+ organizationSlug : organization . slug ,
224+ projectSlug : project . slug ,
225+ environmentSlug : environment . slug ,
226+ } ) ;
227+
228+ const onClickShowNewRuns = ( ) => {
229+ const isPaginated = has ( "cursor" ) || has ( "direction" ) ;
230+ dismissNewRuns ( ) ;
231+ if ( isPaginated ) {
232+ replace ( {
233+ cursor : undefined ,
234+ direction : undefined ,
235+ } ) ;
236+ return ;
237+ }
238+
239+ revalidator . revalidate ( ) ;
240+ } ;
212241
213242 // Shortcut keys for bulk actions
214243 useShortcutKeys ( {
@@ -265,6 +294,20 @@ function RunsList({
265294 rootOnlyDefault = { rootOnlyDefault }
266295 />
267296 < div className = "flex items-center justify-end gap-x-2" >
297+ { showNewRunsBanner && (
298+ < span className = "flex duration-150 animate-in fade-in-0" >
299+ < Button
300+ variant = "secondary/small"
301+ className = "text-text-bright"
302+ onClick = { onClickShowNewRuns }
303+ LeadingIcon = { < PulsingDot className = "h-2 w-2" /> }
304+ tooltip = "Refresh to see new runs"
305+ aria-label = "New runs created. Refresh to see new runs."
306+ >
307+ { newRunsCount >= 100 ? "99+ new runs" : `${ newRunsCount } new runs` }
308+ </ Button >
309+ </ span >
310+ ) }
268311 { ! isShowingBulkActionInspector && (
269312 < LinkButton
270313 variant = "secondary/small"
@@ -303,10 +346,11 @@ function RunsList({
303346 </ div >
304347
305348 < TaskRunsTable
306- total = { list . runs . length }
349+ total = { visibleRuns . length }
307350 hasFilters = { list . hasFilters }
308351 filters = { list . filters }
309- runs = { list . runs }
352+ runs = { visibleRuns }
353+ childrenStatusesBasePath = { childrenStatusesBasePath }
310354 isLoading = { isLoading }
311355 allowSelection
312356 rootOnlyDefault = { rootOnlyDefault }
0 commit comments