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 = function(source) { return new SavedSearch({ id: source.id, name: source.name, filters: mapSavedSearchFilters(source.filters), }) } export const mapSavedSearchToLocationQuery: MapFunction = 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 { 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}`) }