mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Merge pull request #698 from omnivore-app/sort-by-publish-time
Support sort or filter by publish time
This commit is contained in:
commit
f4c65d7fe1
8 changed files with 57 additions and 90 deletions
|
|
@ -8,7 +8,7 @@ import {
|
|||
SearchResponse,
|
||||
} from './types'
|
||||
import {
|
||||
DateRangeFilter,
|
||||
DateFilter,
|
||||
HasFilter,
|
||||
InFilter,
|
||||
LabelFilter,
|
||||
|
|
@ -145,31 +145,16 @@ const appendIncludeLabelFilter = (
|
|||
})
|
||||
}
|
||||
|
||||
const appendSavedDateFilter = (
|
||||
body: SearchBody,
|
||||
filter: DateRangeFilter
|
||||
): void => {
|
||||
body.query.bool.filter.push({
|
||||
range: {
|
||||
savedAt: {
|
||||
gt: filter.startDate,
|
||||
lt: filter.endDate,
|
||||
const appendDateFilters = (body: SearchBody, filters: DateFilter[]): void => {
|
||||
filters.forEach((filter) => {
|
||||
body.query.bool.filter.push({
|
||||
range: {
|
||||
[filter.field]: {
|
||||
gt: filter.startDate,
|
||||
lt: filter.endDate,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const appendPublishedDateFilter = (
|
||||
body: SearchBody,
|
||||
filter: DateRangeFilter
|
||||
): void => {
|
||||
body.query.bool.filter.push({
|
||||
range: {
|
||||
publishedAt: {
|
||||
gt: filter.startDate,
|
||||
lt: filter.endDate,
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -350,10 +335,9 @@ export const searchPages = async (
|
|||
inFilter?: InFilter
|
||||
readFilter?: ReadFilter
|
||||
typeFilter?: PageType
|
||||
labelFilters?: LabelFilter[]
|
||||
hasFilters?: HasFilter[]
|
||||
savedDateFilter?: DateRangeFilter
|
||||
publishedDateFilter?: DateRangeFilter
|
||||
labelFilters: LabelFilter[]
|
||||
hasFilters: HasFilter[]
|
||||
dateFilters: DateFilter[]
|
||||
subscriptionFilter?: SubscriptionFilter
|
||||
includePending?: boolean | null
|
||||
},
|
||||
|
|
@ -367,11 +351,10 @@ export const searchPages = async (
|
|||
query,
|
||||
readFilter = ReadFilter.ALL,
|
||||
typeFilter,
|
||||
labelFilters = [],
|
||||
labelFilters,
|
||||
inFilter = InFilter.ALL,
|
||||
hasFilters = [],
|
||||
savedDateFilter,
|
||||
publishedDateFilter,
|
||||
hasFilters,
|
||||
dateFilters,
|
||||
subscriptionFilter,
|
||||
} = args
|
||||
// default order is descending
|
||||
|
|
@ -435,11 +418,8 @@ export const searchPages = async (
|
|||
if (excludeLabels.length > 0) {
|
||||
appendExcludeLabelFilter(body, excludeLabels)
|
||||
}
|
||||
if (savedDateFilter) {
|
||||
appendSavedDateFilter(body, savedDateFilter)
|
||||
}
|
||||
if (publishedDateFilter) {
|
||||
appendPublishedDateFilter(body, publishedDateFilter)
|
||||
if (dateFilters.length > 0) {
|
||||
appendDateFilters(body, dateFilters)
|
||||
}
|
||||
if (subscriptionFilter) {
|
||||
appendSubscriptionFilter(body, subscriptionFilter)
|
||||
|
|
|
|||
|
|
@ -25,12 +25,7 @@ export interface SearchBody {
|
|||
}
|
||||
| {
|
||||
range: {
|
||||
savedAt: { gt: Date | undefined } | { lt: Date | undefined }
|
||||
}
|
||||
}
|
||||
| {
|
||||
range: {
|
||||
publishedAt: { gt: Date | undefined } | { lt: Date | undefined }
|
||||
[K: string]: { gt: Date | undefined } | { lt: Date | undefined }
|
||||
}
|
||||
}
|
||||
| {
|
||||
|
|
|
|||
|
|
@ -1640,6 +1640,7 @@ export type SignupSuccess = {
|
|||
};
|
||||
|
||||
export enum SortBy {
|
||||
PublishedAt = 'PUBLISHED_AT',
|
||||
SavedAt = 'SAVED_AT',
|
||||
Score = 'SCORE',
|
||||
UpdatedTime = 'UPDATED_TIME'
|
||||
|
|
|
|||
|
|
@ -1216,6 +1216,7 @@ type SignupSuccess {
|
|||
}
|
||||
|
||||
enum SortBy {
|
||||
PUBLISHED_AT
|
||||
SAVED_AT
|
||||
SCORE
|
||||
UPDATED_TIME
|
||||
|
|
|
|||
|
|
@ -448,16 +448,7 @@ export const getArticlesResolver = authorized<
|
|||
event: 'get_articles',
|
||||
properties: {
|
||||
env: env.server.apiEnv,
|
||||
query: searchQuery.query,
|
||||
inFilter: searchQuery.inFilter,
|
||||
readFilter: searchQuery.readFilter,
|
||||
typeFilter: searchQuery.typeFilter,
|
||||
labelFilters: searchQuery.labelFilters,
|
||||
sortParams: searchQuery.sortParams,
|
||||
hasFilters: searchQuery.hasFilters,
|
||||
savedDateFilter: searchQuery.savedDateFilter,
|
||||
publishedDateFilter: searchQuery.publishedDateFilter,
|
||||
subscriptionFilter: searchQuery.subscriptionFilter,
|
||||
...searchQuery,
|
||||
},
|
||||
})
|
||||
|
||||
|
|
@ -466,16 +457,8 @@ export const getArticlesResolver = authorized<
|
|||
from: Number(startCursor),
|
||||
size: first + 1, // fetch one more item to get next cursor
|
||||
sort: searchQuery.sortParams,
|
||||
query: searchQuery.query,
|
||||
inFilter: searchQuery.inFilter,
|
||||
readFilter: searchQuery.readFilter,
|
||||
typeFilter: searchQuery.typeFilter,
|
||||
labelFilters: searchQuery.labelFilters,
|
||||
hasFilters: searchQuery.hasFilters,
|
||||
savedDateFilter: searchQuery.savedDateFilter,
|
||||
publishedDateFilter: searchQuery.publishedDateFilter,
|
||||
subscriptionFilter: searchQuery.subscriptionFilter,
|
||||
includePending: params.includePending,
|
||||
...searchQuery,
|
||||
},
|
||||
claims.uid
|
||||
)) || [[], 0]
|
||||
|
|
@ -818,16 +801,8 @@ export const searchResolver = authorized<
|
|||
userId: claims.uid,
|
||||
event: 'search',
|
||||
properties: {
|
||||
query: searchQuery.query,
|
||||
inFilter: searchQuery.inFilter,
|
||||
readFilter: searchQuery.readFilter,
|
||||
typeFilter: searchQuery.typeFilter,
|
||||
labelFilters: searchQuery.labelFilters,
|
||||
sortParams: searchQuery.sortParams,
|
||||
hasFilters: searchQuery.hasFilters,
|
||||
savedDateFilter: searchQuery.savedDateFilter,
|
||||
publishedDateFilter: searchQuery.publishedDateFilter,
|
||||
env: env.server.apiEnv,
|
||||
...searchQuery,
|
||||
},
|
||||
})
|
||||
|
||||
|
|
@ -853,16 +828,8 @@ export const searchResolver = authorized<
|
|||
from: Number(startCursor),
|
||||
size: first + 1, // fetch one more item to get next cursor
|
||||
sort: searchQuery.sortParams,
|
||||
query: searchQuery.query,
|
||||
inFilter: searchQuery.inFilter,
|
||||
readFilter: searchQuery.readFilter,
|
||||
typeFilter: searchQuery.typeFilter,
|
||||
labelFilters: searchQuery.labelFilters,
|
||||
hasFilters: searchQuery.hasFilters,
|
||||
savedDateFilter: searchQuery.savedDateFilter,
|
||||
publishedDateFilter: searchQuery.publishedDateFilter,
|
||||
subscriptionFilter: searchQuery.subscriptionFilter,
|
||||
includePending: true,
|
||||
...searchQuery,
|
||||
},
|
||||
claims.uid
|
||||
)) || [[], 0]
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ const schema = gql`
|
|||
UPDATED_TIME
|
||||
SCORE
|
||||
SAVED_AT
|
||||
PUBLISHED_AT
|
||||
}
|
||||
|
||||
enum ContentReader {
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ export type SearchFilter = {
|
|||
labelFilters: LabelFilter[]
|
||||
sortParams?: SortParams
|
||||
hasFilters: HasFilter[]
|
||||
savedDateFilter?: DateRangeFilter
|
||||
publishedDateFilter?: DateRangeFilter
|
||||
dateFilters: DateFilter[]
|
||||
subscriptionFilter?: SubscriptionFilter
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +50,8 @@ export enum HasFilter {
|
|||
SHARED_AT,
|
||||
}
|
||||
|
||||
export type DateRangeFilter = {
|
||||
export interface DateFilter {
|
||||
field: string
|
||||
startDate?: Date
|
||||
endDate?: Date
|
||||
}
|
||||
|
|
@ -60,6 +60,7 @@ export enum SortBy {
|
|||
SAVED = 'savedAt',
|
||||
UPDATED = 'updatedAt',
|
||||
SCORE = '_score',
|
||||
PUBLISHED = 'publishedAt',
|
||||
}
|
||||
|
||||
export enum SortOrder {
|
||||
|
|
@ -67,7 +68,7 @@ export enum SortOrder {
|
|||
DESCENDING = 'desc',
|
||||
}
|
||||
|
||||
export type SortParams = {
|
||||
export interface SortParams {
|
||||
by: SortBy
|
||||
order?: SortOrder
|
||||
}
|
||||
|
|
@ -171,6 +172,11 @@ const parseSortParams = (str?: string): SortParams | undefined => {
|
|||
return {
|
||||
by: SortBy.SCORE,
|
||||
}
|
||||
case 'PUBLISHED':
|
||||
return {
|
||||
by: SortBy.PUBLISHED,
|
||||
order: sortOrder,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -185,7 +191,10 @@ const parseHasFilter = (str?: string): HasFilter | undefined => {
|
|||
}
|
||||
}
|
||||
|
||||
const parseDateRangeFilter = (str?: string): DateRangeFilter | undefined => {
|
||||
const parseDateFilter = (
|
||||
field: string,
|
||||
str?: string
|
||||
): DateFilter | undefined => {
|
||||
if (str === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
|
@ -194,7 +203,16 @@ const parseDateRangeFilter = (str?: string): DateRangeFilter | undefined => {
|
|||
const startDate = start && start !== '*' ? new Date(start) : undefined
|
||||
const endDate = end && end !== '*' ? new Date(end) : undefined
|
||||
|
||||
switch (field.toUpperCase()) {
|
||||
case 'PUBLISHED':
|
||||
field = 'publishedAt'
|
||||
break
|
||||
case 'SAVED':
|
||||
field = 'savedAt'
|
||||
}
|
||||
|
||||
return {
|
||||
field,
|
||||
startDate,
|
||||
endDate,
|
||||
}
|
||||
|
|
@ -220,6 +238,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => {
|
|||
inFilter: searchQuery ? InFilter.ALL : InFilter.INBOX,
|
||||
labelFilters: [],
|
||||
hasFilters: [],
|
||||
dateFilters: [],
|
||||
}
|
||||
|
||||
if (!searchQuery) {
|
||||
|
|
@ -229,6 +248,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => {
|
|||
readFilter: ReadFilter.ALL,
|
||||
labelFilters: [],
|
||||
hasFilters: [],
|
||||
dateFilters: [],
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -296,11 +316,11 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => {
|
|||
break
|
||||
}
|
||||
case 'saved':
|
||||
result.savedDateFilter = parseDateRangeFilter(keyword.value)
|
||||
break
|
||||
case 'published':
|
||||
result.publishedDateFilter = parseDateRangeFilter(keyword.value)
|
||||
case 'published': {
|
||||
const dateFilter = parseDateFilter(keyword.keyword, keyword.value)
|
||||
dateFilter && result.dateFilters.push(dateFilter)
|
||||
break
|
||||
}
|
||||
case 'subscription':
|
||||
result.subscriptionFilter = parseSubscriptionFilter(keyword.value)
|
||||
break
|
||||
|
|
|
|||
|
|
@ -148,6 +148,8 @@ describe('elastic api', () => {
|
|||
it('searches pages', async () => {
|
||||
const searchResults = await searchPages(
|
||||
{
|
||||
dateFilters: [],
|
||||
hasFilters: [],
|
||||
inFilter: InFilter.ALL,
|
||||
labelFilters: [],
|
||||
readFilter: ReadFilter.ALL,
|
||||
|
|
|
|||
Loading…
Reference in a new issue