@prefecthq/prefect-ui-library
Version:
This library is the Vue and Typescript component library for [Prefect 2](https://github.com/PrefectHQ/prefect) and [Prefect Cloud 2](https://www.prefect.io/cloud/). _The components and utilities in this project are not meant to be used independently_.
143 lines (116 loc) • 4.6 kB
text/typescript
import { DateRangeSelectAroundValue, DateRangeSelectRangeValue, DateRangeSelectSpanValue, DateRangeSelectValue, DateRangeSelectPeriodValue } from '@prefecthq/prefect-design'
import { LocationQuery } from 'vue-router'
import { SavedSearchFilterResponse, SavedSearchResponse, isDateRangeResponse, isDateRangeRangeResponse, isDateRangeAroundResponse, isDateRangeSpanResponse, isDateRangePeriodResponse } from '@/models/api/SavedSearchResponse'
import { SavedSearch, SavedSearchFilter } from '@/models/SavedSearch'
import { MapFunction, mapper } from '@/services/Mapper'
import { asArray, filterRangePastWeek, isString, isStringArray, mapStateTypeOrNameToStateName } from '@/utilities'
export const mapSavedSearchResponseToSavedSearch: MapFunction<SavedSearchResponse, SavedSearch> = function(source) {
return new SavedSearch({
id: source.id,
name: source.name,
filters: mapSavedSearchFilters(source.filters),
})
}
export const mapSavedSearchToLocationQuery: MapFunction<SavedSearchFilter, LocationQuery> = function(filter) {
const query: LocationQuery = {}
if (filter.deployment?.length) {
query.deployment = filter.deployment
}
if (filter.flow?.length) {
query.flow = filter.flow
}
if (filter.workPool?.length) {
query.workPool = filter.workPool
}
if (filter.workQueue?.length) {
query.workQueue = filter.workQueue
}
if (filter.tag?.length) {
query.tag = filter.tag
}
if (filter.state?.length) {
query.state = filter.state
}
const { range } = filter
switch (range.type) {
case 'around':
query.type = 'around'
query.date = this.map('Date', range.date, 'string')
query.unit = range.unit
query.quantity = range.quantity.toString()
break
case 'period':
query.type = 'period'
query.period = range.period
break
case 'range':
query.type = 'range'
query.startDate = this.map('Date', range.startDate, 'string')
query.endDate = this.map('Date', range.endDate, 'string')
break
case 'span':
query.type = 'span'
query.seconds = range.seconds.toString()
break
default:
const exhaustive: never = range
// eslint-disable-next-line @typescript-eslint/no-explicit-any
throw new Error(`Mapping saved search filters.range missing case for: ${(exhaustive as any).type}`)
}
return query
}
function mapSavedSearchFilters(filters: SavedSearchFilterResponse[] = []): SavedSearchFilter {
const filter: SavedSearchFilter = {
state: getStateFilter(filters),
flow: getObjectFilter(filters, 'flow'),
tag: getObjectFilter(filters, 'tag'),
deployment: getObjectFilter(filters, 'deployment'),
workQueue: getObjectFilter(filters, 'workQueue'),
workPool: getObjectFilter(filters, 'workPool'),
range: getRangeFilter(filters),
}
return filter
}
type SavedSearchProperty = 'flow' | 'tag' | 'deployment' | 'workQueue' | 'workPool' | 'state'
function getObjectFilter(filters: SavedSearchFilterResponse[], property: SavedSearchProperty): string[] {
const filter = filters.find(filter => filter.property === property)
if (!filter || !(isString(filter.value) || isStringArray(filter.value))) {
return []
}
return asArray(filter.value)
}
function getStateFilter(filters: SavedSearchFilterResponse[]): string[] {
const states = getObjectFilter(filters, 'state')
return states.map(state => mapStateTypeOrNameToStateName(state))
}
function getRangeFilter(filters: SavedSearchFilterResponse[]): NonNullable<DateRangeSelectValue> {
const filter = filters.find(filter => filter.property === 'range')
if (!filter || !isDateRangeResponse(filter.value)) {
return filterRangePastWeek
}
const range = filter.value
if (isDateRangeRangeResponse(range)) {
return {
type: 'range',
startDate: mapper.map('string', range.startDate, 'Date'),
endDate: mapper.map('string', range.endDate, 'Date'),
} satisfies DateRangeSelectRangeValue
}
if (isDateRangeAroundResponse(range)) {
return {
type: 'around',
date: mapper.map('string', range.date, 'Date'),
unit: range.unit,
quantity: range.quantity,
} satisfies DateRangeSelectAroundValue
}
if (isDateRangeSpanResponse(range)) {
return range satisfies DateRangeSelectSpanValue
}
if (isDateRangePeriodResponse(range)) {
return range satisfies DateRangeSelectPeriodValue
}
const exhaustive: never = range
// eslint-disable-next-line @typescript-eslint/no-explicit-any
throw new Error(`No handler for date range type: ${(exhaustive as any).type}`)
}