Skip to content

Commit

Permalink
Circulars Sort Results by Relevance (#1829)
Browse files Browse the repository at this point in the history
  • Loading branch information
tylerbarna authored Feb 14, 2024
1 parent ecafd6b commit 8139725
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 5 deletions.
113 changes: 113 additions & 0 deletions app/routes/_gcn.circulars._archive._index/SortSelectorButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*!
* Copyright © 2023 United States Government as represented by the
* Administrator of the National Aeronautics and Space Administration.
* All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
import { useSubmit } from '@remix-run/react'
import {
Button,
ButtonGroup,
CardBody,
Grid,
Icon,
Radio,
} from '@trussworks/react-uswds'
import classNames from 'classnames'
import type { ChangeEvent } from 'react'
import { useState } from 'react'

import DetailsDropdownContent from '~/components/DetailsDropdownContent'

const sortOptions = { circularID: 'Date', relevance: 'Relevance' }

function SortButton({
sort,
expanded,
...props
}: {
sort?: string
expanded?: boolean
} & Omit<Parameters<typeof ButtonGroup>[0], 'segmented' | 'children'>) {
const slimClasses = 'height-4 padding-y-0'

return (
<ButtonGroup type="segmented" {...props}>
<Button type="button" className={`${slimClasses} padding-x-2`}>
Sorted By{' '}
{sortOptions[sort as keyof typeof sortOptions] ||
sortOptions.circularID}
</Button>
<Button type="button" className={`${slimClasses} padding-x-2`}>
{<Icon.FilterList role="presentation" />}
{expanded ? (
<Icon.ExpandLess role="presentation" />
) : (
<Icon.ExpandMore role="presentation" />
)}
</Button>
</ButtonGroup>
)
}

export function SortSelector({
form,
defaultValue,
}: {
form?: string
defaultValue?: string
}) {
const [showContent, setShowContent] = useState(false)

const submit = useSubmit()

function radioOnChange({ target }: ChangeEvent<HTMLInputElement>) {
setShowContent(false)
if (target.form) submit(target.form)
}

const sanitizedValue =
defaultValue && defaultValue in sortOptions ? defaultValue : 'circularID'

const SortRadioButtons = () => (
<>
{Object.entries(sortOptions).map(([value, label]) => (
<Radio
key={value}
id={value}
name="sort"
value={value}
label={label}
form={form}
defaultChecked={sanitizedValue === value}
onChange={radioOnChange}
/>
))}
</>
)

return (
<>
<SortButton
sort={sanitizedValue}
expanded={showContent}
onClick={() => {
setShowContent((shown) => !shown)
}}
/>

<DetailsDropdownContent
className={classNames('maxw-card-xlg', {
'display-none': !showContent,
})}
>
<CardBody>
<Grid col={1}>
<SortRadioButtons />
</Grid>
</CardBody>
</DetailsDropdownContent>
</>
)
}
5 changes: 5 additions & 0 deletions app/routes/_gcn.circulars._archive._index/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import CircularPagination from './CircularPagination'
import CircularsHeader from './CircularsHeader'
import CircularsIndex from './CircularsIndex'
import { DateSelector } from './DateSelectorMenu'
import { SortSelector } from './SortSelectorButton'
import Hint from '~/components/Hint'
import { getFormDataString } from '~/lib/utils'

Expand All @@ -52,12 +53,14 @@ export async function loader({ request: { url } }: LoaderFunctionArgs) {
const endDate = searchParams.get('endDate') || undefined
const page = parseInt(searchParams.get('page') || '1')
const limit = clamp(parseInt(searchParams.get('limit') || '100'), 1, 100)
const sort = searchParams.get('sort') || 'circularId'
const results = await search({
query,
page: page - 1,
limit,
startDate,
endDate,
sort,
})

return { page, ...results }
Expand Down Expand Up @@ -105,6 +108,7 @@ export default function () {
const query = searchParams.get('query') || undefined
const startDate = searchParams.get('startDate') || undefined
const endDate = searchParams.get('endDate') || undefined
const sort = searchParams.get('sort') || 'circularID'

let searchString = searchParams.toString()
if (searchString) searchString = `?${searchString}`
Expand Down Expand Up @@ -153,6 +157,7 @@ export default function () {
defaultStartDate={startDate}
defaultEndDate={endDate}
/>
<SortSelector form={formId} defaultValue={sort} />
<Link to={`/circulars/new${searchString}`}>
<Button
type="button"
Expand Down
17 changes: 12 additions & 5 deletions app/routes/_gcn.circulars/circulars.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,14 @@ export async function search({
limit,
startDate,
endDate,
sort,
}: {
query?: string
page?: number
limit?: number
startDate?: string
endDate?: string
sort?: string
}): Promise<{
items: CircularMetadata[]
totalPages: number
Expand All @@ -142,6 +144,15 @@ export async function search({

const [startTime, endTime] = getValidDates(startDate, endDate)

const sortObj =
sort === 'relevance'
? {}
: {
circularId: {
order: 'desc',
},
}

const {
body: {
hits: {
Expand Down Expand Up @@ -174,11 +185,7 @@ export async function search({
},
fields: ['subject'],
_source: false,
sort: {
circularId: {
order: 'desc',
},
},
sort: sortObj,
from: page && limit && page * limit,
size: limit,
track_total_hits: true,
Expand Down

0 comments on commit 8139725

Please sign in to comment.