Skip to content

Commit

Permalink
Merge pull request #137 from lucafaggianelli/dev
Browse files Browse the repository at this point in the history
New release
  • Loading branch information
lucafaggianelli authored Jun 20, 2023
2 parents 5e993d5 + a58c30b commit e7ef348
Show file tree
Hide file tree
Showing 20 changed files with 930 additions and 639 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [0.3.2] - 2023-06-20

### Added
- Add next fire time to pipelines and triggers (#27)
- show run time in runs list (#129)

### Fixed
- change taskrun duration from positive to non-negative (#128)
- specify button type when in form to avoid submit (#133)
- Fix the run pipeline dialog open/close logic
- Show pipeline name in runs list (#127)

[0.3.2]: https://github.com/lucafaggianelli/plombery.git/releases/tag/v0.3.2
3 changes: 1 addition & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "plombery",
"version": "0.3.1",
"version": "0.3.2",
"description": "",
"license": "MIT",
"author": {
Expand All @@ -23,7 +23,6 @@
"@heroicons/react": "^2.0.16",
"@tanstack/react-query": "^4.26.1",
"@tremor/react": "^2.0.2",
"dayjs": "^1.11.7",
"handsontable": "^12.3.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
24 changes: 15 additions & 9 deletions frontend/src/components/LogViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useQuery, useQueryClient } from '@tanstack/react-query'
import {
Badge,
Bold,
Color,
Flex,
Grid,
Expand All @@ -19,7 +20,11 @@ import useWebSocket from 'react-use-websocket'

import { getLogs, getWebsocketUrl } from '@/repository'
import { LogEntry, LogLevel, Pipeline, WebSocketMessage } from '@/types'
import { formatTimestamp, getTasksColors } from '@/utils'
import {
formatNumber,
formatTimestamp,
getTasksColors,
} from '@/utils'
import TracebackInfoDialog from './TracebackInfoDialog'

interface Props {
Expand Down Expand Up @@ -154,14 +159,15 @@ const LogViewer: React.FC<Props> = ({ pipeline, runId }) => {
return (
<TableRow key={log.id}>
<TableCell>
<span className="font-mono text-xs text-slate-500">
{formatTimestamp(log.timestamp)}
</span>
{duration >= 0 && (
<span className="font-mono text-xs text-slate-500 ml-2">
+{duration} ms
</span>
)}
<Text className="font-mono text-xs">
<span>{formatTimestamp(log.timestamp)}</span>

{duration >= 0 && (
<span className="text-slate-400 ml-2">
+{formatNumber(duration)} ms
</span>
)}
</Text>
</TableCell>
<TableCell>
<Badge size="xs" color={LOG_LEVELS_COLORS[log.level]}>
Expand Down
20 changes: 17 additions & 3 deletions frontend/src/components/ManualRunDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,19 @@ const ManualRunDialog: React.FC<Props> = ({ pipeline }) => {
onClose={() => setOpen(false)}
>
<form
method="dialog"
onSubmit={(event) => {
event.preventDefault()

const params = Object.fromEntries(
new FormData(event.target as HTMLFormElement).entries()
)
runPipelineMutation.mutateAsync(params)

try {
runPipelineMutation.mutateAsync(params)
setOpen(false)
} catch (error) {
console.error(error)
}
}}
>
{query.isLoading ? (
Expand All @@ -220,16 +227,23 @@ const ManualRunDialog: React.FC<Props> = ({ pipeline }) => {

<Flex className="justify-end space-x-6 mt-6">
<Button
type="button"
variant="secondary"
color="indigo"
onClick={() => {
setOpen(false)
}}
disabled={runPipelineMutation.isLoading}
>
Close
</Button>

<Button color="indigo" type="submit">
<Button
color="indigo"
type="submit"
icon={PlayIcon}
disabled={runPipelineMutation.isLoading}
>
Run
</Button>
</Flex>
Expand Down
23 changes: 20 additions & 3 deletions frontend/src/components/PipelinesList.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useQuery } from '@tanstack/react-query'
import { Text, Title, Flex, Card, List, Bold, ListItem } from '@tremor/react'
import { Text, Title, Card, List, Bold, ListItem } from '@tremor/react'
import { formatDistanceToNow } from 'date-fns'
import { Link } from 'react-router-dom'
import React from 'react'

import { listPipelines } from '@/repository'
import ManualRunDialog from './ManualRunDialog'
import TriggersList from './TriggersList'

const PipelinesList: React.FC = () => {
const query = useQuery({
Expand All @@ -26,7 +26,7 @@ const PipelinesList: React.FC = () => {

<List>
{pipelines.map((pipeline) => (
<ListItem key={pipeline.id}>
<ListItem key={pipeline.id} className="gap-x-1">
<div className="min-w-0">
<Text className="truncate">
<Bold>
Expand All @@ -38,6 +38,23 @@ const PipelinesList: React.FC = () => {
)}
</div>

{pipeline.hasTrigger() && (
<div
className="min-w-0"
title={pipeline.getNextFireTime()?.toString()}
>
<Text className="truncate">Next fire time</Text>
<Text className="truncate">
<Bold>
{formatDistanceToNow(pipeline.getNextFireTime()!, {
addSuffix: true,
includeSeconds: true,
})}
</Bold>
</Text>
</div>
)}

<ManualRunDialog pipeline={pipeline} />
</ListItem>
))}
Expand Down
29 changes: 25 additions & 4 deletions frontend/src/components/RunsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Text,
Title,
} from '@tremor/react'
import { formatDistanceToNow, differenceInDays } from 'date-fns'
import { useCallback, useEffect, useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import useWebSocket from 'react-use-websocket'
Expand Down Expand Up @@ -96,11 +97,12 @@ const RunsList: React.FC<Props> = ({ pipelineId, runs: _runs, triggerId }) => {
<Card>
<Title>Runs</Title>

<Table>
<TableHead>
<Table className="overflow-auto max-h-[50vh]">
<TableHead className="sticky top-0 bg-white shadow">
<TableRow>
<TableHeaderCell className="text-right">#</TableHeaderCell>
<TableHeaderCell>Status</TableHeaderCell>
{!pipelineId && <TableHeaderCell>Pipeline</TableHeaderCell>}
{!triggerId && <TableHeaderCell>Trigger</TableHeaderCell>}
<TableHeaderCell>Started at</TableHeaderCell>
<TableHeaderCell className="text-right">Duration</TableHeaderCell>
Expand All @@ -121,6 +123,18 @@ const RunsList: React.FC<Props> = ({ pipelineId, runs: _runs, triggerId }) => {
<TableCell>
<StatusBadge status={run.status} />
</TableCell>
{!pipelineId && (
<TableCell>
<Link
to={`/pipelines/${run.pipeline_id}`}
className="link--arrow"
title="View pipeline details"
onClick={(event) => event.stopPropagation()}
>
{run.pipeline_id}
</Link>
</TableCell>
)}
{!triggerId && (
<TableCell>
<Link
Expand All @@ -133,8 +147,15 @@ const RunsList: React.FC<Props> = ({ pipelineId, runs: _runs, triggerId }) => {
</Link>
</TableCell>
)}
<TableCell>
<Text>{formatDateTime(run.start_time)}</Text>
<TableCell title={formatDateTime(run.start_time)}>
<Text>
{differenceInDays(new Date(), run.start_time) <= 1
? formatDistanceToNow(run.start_time, {
addSuffix: true,
includeSeconds: true,
})
: formatDateTime(run.start_time)}
</Text>
</TableCell>
<TableCell className="text-right">
{run.status !== 'running' ? (
Expand Down
11 changes: 9 additions & 2 deletions frontend/src/components/TriggersList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
Badge,
Card,
Table,
TableBody,
Expand All @@ -10,10 +9,10 @@ import {
Text,
Title,
} from '@tremor/react'
import { formatDistanceToNow } from 'date-fns'
import { useNavigate } from 'react-router-dom'

import { Pipeline } from '@/types'
import { formatDateTime } from '@/utils'

interface Props {
pipeline: Pipeline
Expand All @@ -31,8 +30,10 @@ const TriggersList: React.FC<Props> = ({ pipeline }) => {
<TableRow>
<TableHeaderCell>Name</TableHeaderCell>
<TableHeaderCell>Interval</TableHeaderCell>
<TableHeaderCell>Next Fire Time</TableHeaderCell>
</TableRow>
</TableHead>

<TableBody>
{pipeline.triggers.map((trigger) => (
<TableRow
Expand All @@ -46,6 +47,12 @@ const TriggersList: React.FC<Props> = ({ pipeline }) => {
<TableCell>
<Text>{trigger.schedule}</Text>
</TableCell>
<TableCell>
{formatDistanceToNow(pipeline.getNextFireTime()!, {
includeSeconds: true,
addSuffix: true,
})}
</TableCell>
</TableRow>
))}
</TableBody>
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/pages/pipelines/[pipelineId]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { getPipeline, getPipelineRunUrl, listRuns } from '@/repository'
import ManualRunDialog from '@/components/ManualRunDialog'
import TriggersList from '@/components/TriggersList'
import PageLayout from '@/components/PageLayout'
import { Pipeline } from '@/types'

const PipelineView: React.FC = () => {
const urlParams = useParams()
Expand All @@ -32,7 +33,7 @@ const PipelineView: React.FC = () => {
const pipelineQuery = useQuery({
queryKey: ['pipeline', pipelineId],
queryFn: () => getPipeline(pipelineId),
initialData: { id: '', name: '', description: '', tasks: [], triggers: [] },
initialData: new Pipeline('', '', '', [], []),
enabled: !!pipelineId,
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ import {
getTriggerRunUrl,
runPipelineTrigger,
} from '@/repository'
import { formatDateTime } from '@/utils'
import { Trigger } from '@/types'
import { Pipeline, Trigger } from '@/types'

const TriggerView: React.FC = () => {
const urlParams = useParams()
Expand All @@ -41,7 +40,7 @@ const TriggerView: React.FC = () => {
const pipelineQuery = useQuery({
queryKey: ['pipeline', pipelineId],
queryFn: () => getPipeline(pipelineId),
initialData: { id: '', name: '', description: '', tasks: [], triggers: [] },
initialData: new Pipeline('', '', '', [], []),
enabled: !!pipelineId,
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { useQuery, useQueryClient } from '@tanstack/react-query'
import { Card, CategoryBar, Flex, Grid, Metric, Text, Title } from '@tremor/react'
import {
Bold,
Card,
CategoryBar,
Flex,
Grid,
Metric,
Text,
Title,
} from '@tremor/react'
import { addMilliseconds, isSameDay } from 'date-fns'
import { useParams } from 'react-router-dom'
import useWebSocket from 'react-use-websocket'
import { useEffect } from 'react'
Expand All @@ -11,8 +21,12 @@ import StatusBadge from '@/components/StatusBadge'
import RunsTasksList from '@/components/Tasks'
import { MANUAL_TRIGGER } from '@/constants'
import { getPipeline, getRun, getWebsocketUrl } from '@/repository'
import { Trigger, WebSocketMessage } from '@/types'
import { TASKS_COLORS, getTasksColors } from '@/utils'
import { Pipeline, Trigger, WebSocketMessage } from '@/types'
import {
TASKS_COLORS,
formatDate,
formatTimestamp,
} from '@/utils'

const RunViewPage = () => {
const { lastJsonMessage } = useWebSocket(getWebsocketUrl().toString())
Expand All @@ -39,7 +53,7 @@ const RunViewPage = () => {
const pipelineQuery = useQuery({
queryKey: ['pipeline', pipelineId],
queryFn: () => getPipeline(pipelineId),
initialData: { id: '', name: '', description: '', tasks: [], triggers: [] },
initialData: new Pipeline('', '', '', [], []),
enabled: !!pipelineId,
})

Expand All @@ -66,8 +80,15 @@ const RunViewPage = () => {
return <div>Trigger not found</div>
}

const totalTasksDuration = (run.tasks_run || []).reduce((tot, cur) => tot + cur.duration, 0)
const tasksRunDurations = (run.tasks_run || []).map(tr => tr.duration / totalTasksDuration * 100)
const totalTasksDuration = (run.tasks_run || []).reduce(
(tot, cur) => tot + cur.duration,
0
)
const tasksRunDurations = (run.tasks_run || []).map((tr) =>
totalTasksDuration ? (tr.duration / totalTasksDuration) * 100 : 0
)

const runEndTime = addMilliseconds(run.start_time, run.duration)

return (
<PageLayout
Expand Down Expand Up @@ -97,6 +118,24 @@ const RunViewPage = () => {
showLabels={false}
className="mt-3"
/>

<Flex alignItems="start" className="mt-2">
<div>
<Text>
<Bold>{formatTimestamp(run.start_time)}</Bold>
</Text>
<Text className="mt-1">{formatDate(run.start_time)}</Text>
</div>

<div className="text-right">
<Text>
<Bold>{formatTimestamp(runEndTime)}</Bold>
</Text>
{!isSameDay(run.start_time, runEndTime) && (
<Text>{formatDate(runEndTime)}</Text>
)}
</div>
</Flex>
</Card>
</Grid>

Expand Down
Loading

0 comments on commit e7ef348

Please sign in to comment.