From 84f7334a0650591fe60743b2d98d1cb019bcdeb4 Mon Sep 17 00:00:00 2001 From: abelanger5 Date: Tue, 20 Aug 2024 11:29:32 -0400 Subject: [PATCH] feat: add windows for metrics and selector (#794) * feat: add windows for metrics and selector * better placeholder --- .../openapi/paths/workflow/workflow.yaml | 32 ++ api/v1/server/handlers/workflows/list_runs.go | 8 + .../server/handlers/workflows/metrics_runs.go | 8 + api/v1/server/oas/gen/openapi.gen.go | 368 ++++++++++-------- frontend/app/src/lib/api/generated/Api.ts | 24 ++ frontend/app/src/lib/atoms.ts | 20 +- .../components/workflow-runs-table.tsx | 69 +++- pkg/client/rest/gen.go | 76 ++++ .../prisma/dbsqlc/workflow_runs.sql | 16 + .../prisma/dbsqlc/workflow_runs.sql.go | 88 +++-- pkg/repository/prisma/workflow_run.go | 13 + pkg/repository/workflow_run.go | 9 + 12 files changed, 531 insertions(+), 200 deletions(-) diff --git a/api-contracts/openapi/paths/workflow/workflow.yaml b/api-contracts/openapi/paths/workflow/workflow.yaml index 979a059ca..e60280707 100644 --- a/api-contracts/openapi/paths/workflow/workflow.yaml +++ b/api-contracts/openapi/paths/workflow/workflow.yaml @@ -419,6 +419,22 @@ workflowRuns: type: array items: type: string + - description: The time after the workflow run was created + in: query + name: createdAfter + example: "2021-01-01T00:00:00Z" + required: false + schema: + type: string + format: date-time + - description: The time before the workflow run was created + in: query + name: createdBefore + example: "2021-01-01T00:00:00Z" + required: false + schema: + type: string + format: date-time - description: The order by field in: query name: orderByField @@ -513,6 +529,22 @@ workflowRunsMetrics: type: array items: type: string + - description: The time after the workflow run was created + in: query + name: createdAfter + example: "2021-01-01T00:00:00Z" + required: false + schema: + type: string + format: date-time + - description: The time before the workflow run was created + in: query + name: createdBefore + example: "2021-01-01T00:00:00Z" + required: false + schema: + type: string + format: date-time responses: "200": content: diff --git a/api/v1/server/handlers/workflows/list_runs.go b/api/v1/server/handlers/workflows/list_runs.go index b63d4d2fd..95bd20855 100644 --- a/api/v1/server/handlers/workflows/list_runs.go +++ b/api/v1/server/handlers/workflows/list_runs.go @@ -41,6 +41,14 @@ func (t *WorkflowService) WorkflowRunList(ctx echo.Context, request gen.Workflow listOpts.OrderDirection = &orderDirection } + if request.Params.CreatedAfter != nil { + listOpts.CreatedAfter = request.Params.CreatedAfter + } + + if request.Params.CreatedBefore != nil { + listOpts.CreatedBefore = request.Params.CreatedBefore + } + if request.Params.Limit != nil { limit = int(*request.Params.Limit) listOpts.Limit = &limit diff --git a/api/v1/server/handlers/workflows/metrics_runs.go b/api/v1/server/handlers/workflows/metrics_runs.go index 6547ddf6d..ab384a6f9 100644 --- a/api/v1/server/handlers/workflows/metrics_runs.go +++ b/api/v1/server/handlers/workflows/metrics_runs.go @@ -24,6 +24,14 @@ func (t *WorkflowService) WorkflowRunGetMetrics(ctx echo.Context, request gen.Wo listOpts.WorkflowId = &workflowIdStr } + if request.Params.CreatedAfter != nil { + listOpts.CreatedAfter = request.Params.CreatedAfter + } + + if request.Params.CreatedBefore != nil { + listOpts.CreatedBefore = request.Params.CreatedBefore + } + if request.Params.EventId != nil { eventIdStr := request.Params.EventId.String() listOpts.EventId = &eventIdStr diff --git a/api/v1/server/oas/gen/openapi.gen.go b/api/v1/server/oas/gen/openapi.gen.go index 51eeb41ff..b3684f146 100644 --- a/api/v1/server/oas/gen/openapi.gen.go +++ b/api/v1/server/oas/gen/openapi.gen.go @@ -1308,6 +1308,12 @@ type WorkflowRunListParams struct { // AdditionalMetadata A list of metadata key value pairs to filter by AdditionalMetadata *[]string `form:"additionalMetadata,omitempty" json:"additionalMetadata,omitempty"` + // CreatedAfter The time after the workflow run was created + CreatedAfter *time.Time `form:"createdAfter,omitempty" json:"createdAfter,omitempty"` + + // CreatedBefore The time before the workflow run was created + CreatedBefore *time.Time `form:"createdBefore,omitempty" json:"createdBefore,omitempty"` + // OrderByField The order by field OrderByField *WorkflowRunOrderByField `form:"orderByField,omitempty" json:"orderByField,omitempty"` @@ -1331,6 +1337,12 @@ type WorkflowRunGetMetricsParams struct { // AdditionalMetadata A list of metadata key value pairs to filter by AdditionalMetadata *[]string `form:"additionalMetadata,omitempty" json:"additionalMetadata,omitempty"` + + // CreatedAfter The time after the workflow run was created + CreatedAfter *time.Time `form:"createdAfter,omitempty" json:"createdAfter,omitempty"` + + // CreatedBefore The time before the workflow run was created + CreatedBefore *time.Time `form:"createdBefore,omitempty" json:"createdBefore,omitempty"` } // WorkerGetParams defines parameters for WorkerGet. @@ -2888,6 +2900,20 @@ func (w *ServerInterfaceWrapper) WorkflowRunList(ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter additionalMetadata: %s", err)) } + // ------------- Optional query parameter "createdAfter" ------------- + + err = runtime.BindQueryParameter("form", true, false, "createdAfter", ctx.QueryParams(), ¶ms.CreatedAfter) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter createdAfter: %s", err)) + } + + // ------------- Optional query parameter "createdBefore" ------------- + + err = runtime.BindQueryParameter("form", true, false, "createdBefore", ctx.QueryParams(), ¶ms.CreatedBefore) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter createdBefore: %s", err)) + } + // ------------- Optional query parameter "orderByField" ------------- err = runtime.BindQueryParameter("form", true, false, "orderByField", ctx.QueryParams(), ¶ms.OrderByField) @@ -2959,6 +2985,20 @@ func (w *ServerInterfaceWrapper) WorkflowRunGetMetrics(ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter additionalMetadata: %s", err)) } + // ------------- Optional query parameter "createdAfter" ------------- + + err = runtime.BindQueryParameter("form", true, false, "createdAfter", ctx.QueryParams(), ¶ms.CreatedAfter) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter createdAfter: %s", err)) + } + + // ------------- Optional query parameter "createdBefore" ------------- + + err = runtime.BindQueryParameter("form", true, false, "createdBefore", ctx.QueryParams(), ¶ms.CreatedBefore) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter createdBefore: %s", err)) + } + // Invoke the callback with all the unmarshaled arguments err = w.Handler.WorkflowRunGetMetrics(ctx, tenant, params) return err @@ -8381,169 +8421,171 @@ func (sh *strictHandler) WorkflowVersionGetDefinition(ctx echo.Context, workflow // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", + "+lLajgEA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/frontend/app/src/lib/api/generated/Api.ts b/frontend/app/src/lib/api/generated/Api.ts index cbf722a8b..3ee407e17 100644 --- a/frontend/app/src/lib/api/generated/Api.ts +++ b/frontend/app/src/lib/api/generated/Api.ts @@ -1330,6 +1330,18 @@ export class Api extends HttpClient extends HttpClient diff --git a/frontend/app/src/lib/atoms.ts b/frontend/app/src/lib/atoms.ts index 4542cde4d..8f4924ad4 100644 --- a/frontend/app/src/lib/atoms.ts +++ b/frontend/app/src/lib/atoms.ts @@ -4,13 +4,17 @@ import { useSearchParams } from 'react-router-dom'; import { useEffect, useMemo, useState } from 'react'; import { useQuery } from '@tanstack/react-query'; -const getInitialValue = (key: string): T | undefined => { +const getInitialValue = (key: string, defaultValue?: T): T | undefined => { const item = localStorage.getItem(key); if (item !== null) { return JSON.parse(item) as T; } + if (defaultValue !== undefined) { + return defaultValue; + } + return; }; @@ -121,3 +125,17 @@ export function useTenantContext(): [ return [currTenant || computedCurrTenant, setTenant]; } + +const lastTimeRange = 'lastTimeRange'; + +const lastTimeRangeAtomInit = atom( + getInitialValue(lastTimeRange, '1d'), +); + +export const lastTimeRangeAtom = atom( + (get) => get(lastTimeRangeAtomInit), + (_get, set, newVal: string) => { + set(lastTimeRangeAtomInit, newVal); + localStorage.setItem(lastTimeRange, JSON.stringify(newVal)); + }, +); diff --git a/frontend/app/src/pages/main/workflow-runs/components/workflow-runs-table.tsx b/frontend/app/src/pages/main/workflow-runs/components/workflow-runs-table.tsx index ee14d670c..62ea98d83 100644 --- a/frontend/app/src/pages/main/workflow-runs/components/workflow-runs-table.tsx +++ b/frontend/app/src/pages/main/workflow-runs/components/workflow-runs-table.tsx @@ -34,8 +34,20 @@ import { import { WorkflowRunsMetricsView } from './workflow-runs-metrics'; import queryClient from '@/query-client'; import { useApiError } from '@/lib/hooks'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select'; +import { useAtom } from 'jotai'; +import { lastTimeRangeAtom } from '@/lib/atoms'; +import { Skeleton } from '@/components/ui/skeleton'; export interface WorkflowRunsTableProps { + createdAfter?: string; + createdBefore?: string; workflowId?: string; parentWorkflowRunId?: string; parentStepRunId?: string; @@ -56,6 +68,11 @@ export function WorkflowRunsTable({ const { tenant } = useOutletContext(); invariant(tenant); + const [timeRange, setTimeRange] = useAtom(lastTimeRangeAtom); + const [createdAfter, setCreatedAfter] = useState( + new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), + ); + const [sorting, setSorting] = useState(() => { const sortParam = searchParams.get('sort'); if (sortParam) { @@ -193,6 +210,7 @@ export function WorkflowRunsTable({ orderByDirection, orderByField, additionalMetadata: AdditionalMetadataFilter, + createdAfter, }), refetchInterval, }); @@ -203,6 +221,7 @@ export function WorkflowRunsTable({ parentWorkflowRunId, parentStepRunId, additionalMetadata: AdditionalMetadataFilter, + createdAfter, }), refetchInterval, }); @@ -378,8 +397,8 @@ export function WorkflowRunsTable({ return ( <> - {metricsQuery.data && ( -
+
+ {metricsQuery.data ? ( { @@ -408,9 +427,51 @@ export function WorkflowRunsTable({ }); }} /> -
- )} + ) : ( + + )} + +
No workflow runs found with the given filters.} error={workflowKeysError} isLoading={workflowKeysIsLoading} columns={columns} diff --git a/pkg/client/rest/gen.go b/pkg/client/rest/gen.go index 5268bdf81..1551d8349 100644 --- a/pkg/client/rest/gen.go +++ b/pkg/client/rest/gen.go @@ -1305,6 +1305,12 @@ type WorkflowRunListParams struct { // AdditionalMetadata A list of metadata key value pairs to filter by AdditionalMetadata *[]string `form:"additionalMetadata,omitempty" json:"additionalMetadata,omitempty"` + // CreatedAfter The time after the workflow run was created + CreatedAfter *time.Time `form:"createdAfter,omitempty" json:"createdAfter,omitempty"` + + // CreatedBefore The time before the workflow run was created + CreatedBefore *time.Time `form:"createdBefore,omitempty" json:"createdBefore,omitempty"` + // OrderByField The order by field OrderByField *WorkflowRunOrderByField `form:"orderByField,omitempty" json:"orderByField,omitempty"` @@ -1328,6 +1334,12 @@ type WorkflowRunGetMetricsParams struct { // AdditionalMetadata A list of metadata key value pairs to filter by AdditionalMetadata *[]string `form:"additionalMetadata,omitempty" json:"additionalMetadata,omitempty"` + + // CreatedAfter The time after the workflow run was created + CreatedAfter *time.Time `form:"createdAfter,omitempty" json:"createdAfter,omitempty"` + + // CreatedBefore The time before the workflow run was created + CreatedBefore *time.Time `form:"createdBefore,omitempty" json:"createdBefore,omitempty"` } // WorkerGetParams defines parameters for WorkerGet. @@ -5327,6 +5339,38 @@ func NewWorkflowRunListRequest(server string, tenant openapi_types.UUID, params } + if params.CreatedAfter != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "createdAfter", runtime.ParamLocationQuery, *params.CreatedAfter); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.CreatedBefore != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "createdBefore", runtime.ParamLocationQuery, *params.CreatedBefore); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + if params.OrderByField != nil { if queryFrag, err := runtime.StyleParamWithLocation("form", true, "orderByField", runtime.ParamLocationQuery, *params.OrderByField); err != nil { @@ -5479,6 +5523,38 @@ func NewWorkflowRunGetMetricsRequest(server string, tenant openapi_types.UUID, p } + if params.CreatedAfter != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "createdAfter", runtime.ParamLocationQuery, *params.CreatedAfter); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.CreatedBefore != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "createdBefore", runtime.ParamLocationQuery, *params.CreatedBefore); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + queryURL.RawQuery = queryValues.Encode() } diff --git a/pkg/repository/prisma/dbsqlc/workflow_runs.sql b/pkg/repository/prisma/dbsqlc/workflow_runs.sql index 0923121f8..7e96c0bcc 100644 --- a/pkg/repository/prisma/dbsqlc/workflow_runs.sql +++ b/pkg/repository/prisma/dbsqlc/workflow_runs.sql @@ -63,6 +63,10 @@ WITH runs AS ( sqlc.narg('createdAfter')::timestamp IS NULL OR runs."createdAt" > sqlc.narg('createdAfter')::timestamp ) AND + ( + sqlc.narg('createdBefore')::timestamp IS NULL OR + runs."createdAt" < sqlc.narg('createdBefore')::timestamp + ) AND ( sqlc.narg('finishedAfter')::timestamp IS NULL OR runs."finishedAt" > sqlc.narg('finishedAfter')::timestamp @@ -98,6 +102,14 @@ LEFT JOIN WHERE runs."tenantId" = @tenantId::uuid AND runs."createdAt" > NOW() - INTERVAL '1 day' AND + ( + sqlc.narg('createdAfter')::timestamp IS NULL OR + runs."createdAt" > sqlc.narg('createdAfter')::timestamp + ) AND + ( + sqlc.narg('createdBefore')::timestamp IS NULL OR + runs."createdAt" < sqlc.narg('createdBefore')::timestamp + ) AND runs."deletedAt" IS NULL AND workflowVersion."deletedAt" IS NULL AND workflow."deletedAt" IS NULL AND @@ -192,6 +204,10 @@ WHERE sqlc.narg('createdAfter')::timestamp IS NULL OR runs."createdAt" > sqlc.narg('createdAfter')::timestamp ) AND + ( + sqlc.narg('createdBefore')::timestamp IS NULL OR + runs."createdAt" < sqlc.narg('createdBefore')::timestamp + ) AND ( sqlc.narg('finishedAfter')::timestamp IS NULL OR runs."finishedAt" > sqlc.narg('finishedAfter')::timestamp diff --git a/pkg/repository/prisma/dbsqlc/workflow_runs.sql.go b/pkg/repository/prisma/dbsqlc/workflow_runs.sql.go index 2d88ac8bc..17de4dc1d 100644 --- a/pkg/repository/prisma/dbsqlc/workflow_runs.sql.go +++ b/pkg/repository/prisma/dbsqlc/workflow_runs.sql.go @@ -78,11 +78,15 @@ WITH runs AS ( ) AND ( $13::timestamp IS NULL OR - runs."finishedAt" > $13::timestamp + runs."createdAt" < $13::timestamp + ) AND + ( + $14::timestamp IS NULL OR + runs."finishedAt" > $14::timestamp ) ORDER BY - case when $14 = 'createdAt ASC' THEN runs."createdAt" END ASC , - case when $14 = 'createdAt DESC' then runs."createdAt" END DESC, + case when $15 = 'createdAt ASC' THEN runs."createdAt" END ASC , + case when $15 = 'createdAt DESC' then runs."createdAt" END DESC, runs."id" ASC LIMIT 10000 ) @@ -105,6 +109,7 @@ type CountWorkflowRunsParams struct { GroupKey pgtype.Text `json:"groupKey"` Statuses []string `json:"statuses"` CreatedAfter pgtype.Timestamp `json:"createdAfter"` + CreatedBefore pgtype.Timestamp `json:"createdBefore"` FinishedAfter pgtype.Timestamp `json:"finishedAfter"` Orderby interface{} `json:"orderby"` } @@ -123,6 +128,7 @@ func (q *Queries) CountWorkflowRuns(ctx context.Context, db DBTX, arg CountWorkf arg.GroupKey, arg.Statuses, arg.CreatedAfter, + arg.CreatedBefore, arg.FinishedAfter, arg.Orderby, ) @@ -1088,22 +1094,26 @@ WHERE ) AND ( $13::timestamp IS NULL OR - runs."finishedAt" > $13::timestamp + runs."createdAt" < $13::timestamp + ) AND + ( + $14::timestamp IS NULL OR + runs."finishedAt" > $14::timestamp ) ORDER BY - case when $14 = 'createdAt ASC' THEN runs."createdAt" END ASC , - case when $14 = 'createdAt DESC' THEN runs."createdAt" END DESC, - case when $14 = 'finishedAt ASC' THEN runs."finishedAt" END ASC , - case when $14 = 'finishedAt DESC' THEN runs."finishedAt" END DESC, - case when $14 = 'startedAt ASC' THEN runs."startedAt" END ASC , - case when $14 = 'startedAt DESC' THEN runs."startedAt" END DESC, - case when $14 = 'duration ASC' THEN runs."duration" END ASC NULLS FIRST, - case when $14 = 'duration DESC' THEN runs."duration" END DESC NULLS LAST, + case when $15 = 'createdAt ASC' THEN runs."createdAt" END ASC , + case when $15 = 'createdAt DESC' THEN runs."createdAt" END DESC, + case when $15 = 'finishedAt ASC' THEN runs."finishedAt" END ASC , + case when $15 = 'finishedAt DESC' THEN runs."finishedAt" END DESC, + case when $15 = 'startedAt ASC' THEN runs."startedAt" END ASC , + case when $15 = 'startedAt DESC' THEN runs."startedAt" END DESC, + case when $15 = 'duration ASC' THEN runs."duration" END ASC NULLS FIRST, + case when $15 = 'duration DESC' THEN runs."duration" END DESC NULLS LAST, runs."id" ASC OFFSET - COALESCE($15, 0) + COALESCE($16, 0) LIMIT - COALESCE($16, 50) + COALESCE($17, 50) ` type ListWorkflowRunsParams struct { @@ -1119,6 +1129,7 @@ type ListWorkflowRunsParams struct { GroupKey pgtype.Text `json:"groupKey"` Statuses []string `json:"statuses"` CreatedAfter pgtype.Timestamp `json:"createdAfter"` + CreatedBefore pgtype.Timestamp `json:"createdBefore"` FinishedAfter pgtype.Timestamp `json:"finishedAfter"` Orderby interface{} `json:"orderby"` Offset interface{} `json:"offset"` @@ -1150,6 +1161,7 @@ func (q *Queries) ListWorkflowRuns(ctx context.Context, db DBTX, arg ListWorkflo arg.GroupKey, arg.Statuses, arg.CreatedAfter, + arg.CreatedBefore, arg.FinishedAfter, arg.Orderby, arg.Offset, @@ -1812,38 +1824,48 @@ LEFT JOIN WHERE runs."tenantId" = $1::uuid AND runs."createdAt" > NOW() - INTERVAL '1 day' AND + ( + $2::timestamp IS NULL OR + runs."createdAt" > $2::timestamp + ) AND + ( + $3::timestamp IS NULL OR + runs."createdAt" < $3::timestamp + ) AND runs."deletedAt" IS NULL AND workflowVersion."deletedAt" IS NULL AND workflow."deletedAt" IS NULL AND - ( - $2::uuid IS NULL OR - workflow."id" = $2::uuid - ) AND - ( - $3::uuid IS NULL OR - runs."parentId" = $3::uuid - ) AND ( $4::uuid IS NULL OR - runs."parentStepRunId" = $4::uuid + workflow."id" = $4::uuid ) AND ( - $5::jsonb IS NULL OR - runs."additionalMetadata" @> $5::jsonb + $5::uuid IS NULL OR + runs."parentId" = $5::uuid ) AND ( $6::uuid IS NULL OR - events."id" = $6::uuid + runs."parentStepRunId" = $6::uuid + ) AND + ( + $7::jsonb IS NULL OR + runs."additionalMetadata" @> $7::jsonb + ) AND + ( + $8::uuid IS NULL OR + events."id" = $8::uuid ) ` type WorkflowRunsMetricsCountParams struct { - Tenantid pgtype.UUID `json:"tenantid"` - WorkflowId pgtype.UUID `json:"workflowId"` - ParentId pgtype.UUID `json:"parentId"` - ParentStepRunId pgtype.UUID `json:"parentStepRunId"` - AdditionalMetadata []byte `json:"additionalMetadata"` - EventId pgtype.UUID `json:"eventId"` + Tenantid pgtype.UUID `json:"tenantid"` + CreatedAfter pgtype.Timestamp `json:"createdAfter"` + CreatedBefore pgtype.Timestamp `json:"createdBefore"` + WorkflowId pgtype.UUID `json:"workflowId"` + ParentId pgtype.UUID `json:"parentId"` + ParentStepRunId pgtype.UUID `json:"parentStepRunId"` + AdditionalMetadata []byte `json:"additionalMetadata"` + EventId pgtype.UUID `json:"eventId"` } type WorkflowRunsMetricsCountRow struct { @@ -1857,6 +1879,8 @@ type WorkflowRunsMetricsCountRow struct { func (q *Queries) WorkflowRunsMetricsCount(ctx context.Context, db DBTX, arg WorkflowRunsMetricsCountParams) (*WorkflowRunsMetricsCountRow, error) { row := db.QueryRow(ctx, workflowRunsMetricsCount, arg.Tenantid, + arg.CreatedAfter, + arg.CreatedBefore, arg.WorkflowId, arg.ParentId, arg.ParentStepRunId, diff --git a/pkg/repository/prisma/workflow_run.go b/pkg/repository/prisma/workflow_run.go index 684562a69..78d3fe3df 100644 --- a/pkg/repository/prisma/workflow_run.go +++ b/pkg/repository/prisma/workflow_run.go @@ -536,6 +536,11 @@ func listWorkflowRuns(ctx context.Context, pool *pgxpool.Pool, queries *dbsqlc.Q queryParams.CreatedAfter = sqlchelpers.TimestampFromTime(*opts.CreatedAfter) } + if opts.CreatedBefore != nil { + countParams.CreatedBefore = sqlchelpers.TimestampFromTime(*opts.CreatedBefore) + queryParams.CreatedBefore = sqlchelpers.TimestampFromTime(*opts.CreatedBefore) + } + if opts.FinishedAfter != nil { countParams.FinishedAfter = sqlchelpers.TimestampFromTime(*opts.FinishedAfter) queryParams.FinishedAfter = sqlchelpers.TimestampFromTime(*opts.FinishedAfter) @@ -624,6 +629,14 @@ func workflowRunMetricsCount(ctx context.Context, pool *pgxpool.Pool, queries *d queryParams.EventId = pgEventId } + if opts.CreatedAfter != nil { + queryParams.CreatedAfter = sqlchelpers.TimestampFromTime(*opts.CreatedAfter) + } + + if opts.CreatedBefore != nil { + queryParams.CreatedBefore = sqlchelpers.TimestampFromTime(*opts.CreatedBefore) + } + if opts.AdditionalMetadata != nil { additionalMetadataBytes, err := json.Marshal(opts.AdditionalMetadata) if err != nil { diff --git a/pkg/repository/workflow_run.go b/pkg/repository/workflow_run.go index 1fbd13519..b87d16214 100644 --- a/pkg/repository/workflow_run.go +++ b/pkg/repository/workflow_run.go @@ -291,6 +291,9 @@ type ListWorkflowRunsOpts struct { // (optional) a time after which the run was created CreatedAfter *time.Time + // (optional) a time before which the run was created + CreatedBefore *time.Time + // (optional) a time before which the run was finished FinishedAfter *time.Time @@ -316,6 +319,12 @@ type WorkflowRunsMetricsOpts struct { // (optional) exact metadata to filter by AdditionalMetadata map[string]interface{} `validate:"omitempty"` + + // (optional) the time the workflow run was created before + CreatedBefore *time.Time `validate:"omitempty"` + + // (optional) the time the workflow run was created after + CreatedAfter *time.Time `validate:"omitempty"` } type ListWorkflowRunsResult struct {