Skip to content

Commit

Permalink
Merge pull request #878 from PrefectHQ/design-filters
Browse files Browse the repository at this point in the history
pulled out orion-design parts of extract-filters
  • Loading branch information
Evan Sutherland authored Jan 25, 2022
2 parents 0c33c36 + 90b5506 commit f19896e
Show file tree
Hide file tree
Showing 11 changed files with 390 additions and 242 deletions.
2 changes: 1 addition & 1 deletion orion-ui/packages/orion-design/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@prefecthq/orion-design",
"version": "0.1.4",
"version": "0.1.5",
"private": false,
"keywords": [
"prefect",
Expand Down
164 changes: 164 additions & 0 deletions orion-ui/packages/orion-design/src/services/Filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { Filter, FlowFilter, FlowRunFilter, TaskRunFilter, DeploymentFilter, StateFilter, TimeFrameFilter } from '@/typings/filters'
import { BaseFilter, GlobalFilter, RunState, RunTimeFrame } from '@/typings/global'
import { isNonEmptyArray } from '@/utilities/arrays'
import { isSubState } from '@/utilities/states'
import { calculateEnd, calculateStart, isValidTimeFrame } from '@/utilities/timeFrame'

interface Sortable<T extends Filter> {
sort?: [keyof T],
}

export type DeploymentsFilter = { deployments?: DeploymentFilter } & Sortable<DeploymentFilter>
export type FlowsFilter = { flows?: FlowFilter } & Sortable<FlowFilter>
export type TaskRunsFilter = { task_runs?: TaskRunFilter } & Sortable<TaskRunFilter>
export type FlowRunsFilter = { flow_runs?: FlowRunFilter } & Sortable<FlowRunFilter>

export type UnionFilters =
& FlowsFilter
& DeploymentsFilter
& FlowRunsFilter
& TaskRunsFilter

interface Historical {
history_start: string,
history_end: string,
history_interval_seconds: number,
}

export type TaskRunsHistoryFilter = { task_runs?: TaskRunFilter } & Historical
export type FlowRunsHistoryFilter = { flow_runs?: FlowRunFilter } & Historical


function buildBaseFilter(baseFilter: BaseFilter): Filter {
const filter: Filter = {}

if (isNonEmptyArray(baseFilter.ids)) {
filter.id = { any_: baseFilter.ids }
}

if (isNonEmptyArray(baseFilter.names)) {
filter.name = { any_: baseFilter.names }
}

if (isNonEmptyArray(baseFilter.tags)) {
filter.tags = { all_: baseFilter.tags }
}

return filter
}

function buildTimeFrameFilter(timeFrame: RunTimeFrame | undefined): TimeFrameFilter | undefined {
if (!timeFrame || !isValidTimeFrame(timeFrame.from) && !isValidTimeFrame(timeFrame.from)) {
return undefined
}

let filter: TimeFrameFilter = {}

if (isValidTimeFrame(timeFrame.from)) {
filter = { ...filter, after_: calculateStart(timeFrame.from)!.toISOString() }
}

if (isValidTimeFrame(timeFrame.to)) {
filter = { ...filter, before_: calculateEnd(timeFrame.to)!.toISOString() }
}

return filter
}

function buildStateFilter(states: RunState[] | undefined): StateFilter | undefined {
if (!states || !isNonEmptyArray(states)) {
return undefined
}

let filter: StateFilter = {}

const [stateNames, stateTypes] = states.reduce<[string[], string[]]>(([stateNames, stateTypes], state) => {
if (isSubState(state.name)) {
stateNames.push(state.name)
} else {
stateTypes.push(state.type)
}

return [stateNames, stateTypes]
}, [[], []])

if (stateNames.length > 0) {
filter = { ...filter, name: { any_: stateNames } }
}

if (stateTypes.length > 0) {
filter = { ...filter, type: { any_: stateTypes } }
}

return filter
}

function buildDeploymentFilter(globalFilter: GlobalFilter): DeploymentFilter {
const filter: DeploymentFilter = buildBaseFilter(globalFilter.deployments)

return filter
}

function buildFlowFilter(globalFilter: GlobalFilter): FlowFilter {
const filter: FlowFilter = buildBaseFilter(globalFilter.flows)

return filter
}

function buildFlowRunFilter(globalFilter: GlobalFilter): FlowRunFilter {
const filter: FlowRunFilter = buildBaseFilter(globalFilter.flow_runs)

const startTime = buildTimeFrameFilter(globalFilter.flow_runs.timeframe)
if (startTime) {
filter.expected_start_time = startTime
}

const state = buildStateFilter(globalFilter.flow_runs.states)
if (state) {
filter.state = state
}

return filter
}

function buildTaskRunFilter(globalFilter: GlobalFilter): TaskRunFilter {
const filter: TaskRunFilter = buildBaseFilter(globalFilter.task_runs)

const startTime = buildTimeFrameFilter(globalFilter.task_runs.timeframe)
if (startTime) {
filter.start_time = startTime
}

const state = buildStateFilter(globalFilter.task_runs.states)
if (state) {
filter.state = state
}

return filter
}

export function buildFilter(globalFilter: GlobalFilter): UnionFilters {
const filters: UnionFilters = {}

const deployments = buildDeploymentFilter(globalFilter)
if (Object.keys(deployments).length > 0) {
filters.deployments = deployments
}

const flows = buildFlowFilter(globalFilter)
if (Object.keys(flows).length > 0) {
filters.flows = flows
}

const flowRuns = buildFlowRunFilter(globalFilter)
if (Object.keys(flowRuns).length > 0) {
filters.flow_runs = flowRuns
}

const taskRuns = buildTaskRunFilter(globalFilter)
if (Object.keys(taskRuns).length > 0) {
filters.task_runs = taskRuns
}

return filters
}
61 changes: 61 additions & 0 deletions orion-ui/src/plugins/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,65 @@
import { App, Plugin, ref, ComputedRef, watch, WatchStopHandle } from 'vue'
import {
FlowFilter,
DeploymentFilter,
FlowRunFilter,
TaskRunFilter
} from '@/typings/filters'

interface Endpoint {
method: 'POST' | 'GET' | 'DELETE' | 'PUT'
url: string
interpolate?: boolean
}

interface CreateFlowRunBody {
name?: string
flow_id: string
deployment_id?: string
flow_version?: string
parameters?: { [key: string]: any }
idempotency_key?: string
context?: { [key: string]: any }
tags?: string[]
parent_task_run_id?: string
state?: {
type: string
name?: string
message?: string
data?: any
state_details?: {
flow_run_id?: string
task_run_id?: string
child_flow_run_id?: string
scheduled_time?: string
cache_key?: string
cache_expiration?: string
}
}
}

interface CreateDeploymentFlowRunBody {
id: string
name?: string
parameters?: { [key: string]: any }
idempotency_key?: string
context?: { [key: string]: any }
tags?: string[]
state?: {
type: string
name?: string
message?: string
data?: any
state_details?: {
flow_run_id?: string
task_run_id?: string
child_flow_run_id?: string
scheduled_time?: string
cache_key?: string
cache_expiration?: string
}
}
}

export interface BaseFilter {
flows?: FlowFilter
Expand Down
6 changes: 6 additions & 0 deletions orion-ui/src/store/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import {
FlowRunsFilter,
TaskRunsFilter
} from '@/plugins/api'
import {
FlowFilter,
DeploymentFilter,
FlowRunFilter,
TaskRunFilter
} from '@/typings/filters'
import { State } from '.'
import { GetterTree } from 'vuex'

Expand Down
3 changes: 3 additions & 0 deletions orion-ui/src/types/states.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ export type StateDirection = 1 | -1
export type StateIcon = `pi-${Lowercase<State>}`
export type StateColor = `var(--${Lowercase<State>})`

export const SubStates = ['Late', 'Crashed'] as const
export type SubState = typeof SubStates[number]

export class States {
public static readonly COMPLETED = 'COMPLETED'
public static readonly RUNNING = 'RUNNING'
Expand Down
Loading

0 comments on commit f19896e

Please sign in to comment.