Skip to content

Commit

Permalink
1607 add llm genrated tag (#1655)
Browse files Browse the repository at this point in the history
* add hierarchicalMenu(fake data)

* Update HierarchialMenu

* Update menu with llm data

* Create useHierarchicalMenu and fix add padding to the left of child

* Craete a customize HierarchicalMenuWidget

* update css for llm tag menu

* Delete the parent counting and sort parent Alphabetical

* Baypass typesense error

* Delete the algoliasearch dependncy

* Add Col to testimony Search

* Add refinement

* Implement sorting logic for llm tags display

* Extract the subtitle for filter tags

* Add updated facets into getItems and remove redinment from useHierarachicalMenu

* Run prettier

* Change the iteration and detelet the downlevelIteration

* Add filter to getWidgetSearchParameter
  • Loading branch information
HuanFengYeh authored Jan 16, 2025
1 parent eee343c commit 491fb83
Show file tree
Hide file tree
Showing 8 changed files with 682 additions and 12 deletions.
449 changes: 449 additions & 0 deletions components/search/HierarchicalMenuWidget.tsx

Large diffs are not rendered by default.

101 changes: 101 additions & 0 deletions components/search/SearchContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,105 @@ export const SearchContainer = styled.div`
.ais-RefinementList-label {
border-bottom: dashed 1px;
}
.ais-MultiselectHierarchicalMenu-list {
background-color: white;
padding: 1rem;
border-radius: 4px;
margin-bottom: 1.5rem;
max-height: 250px;
overflow-y: auto;
list-style: none;
}
.ais-MultiselectHierarchicalMenu-item {
font-size: 1rem;
border-bottom: dashed 1px;
}
.ais-MultiselectHierarchicalMenu-label {
white-space: normal;
display: flex;
width: 100%;
align-items: center;
gap: 10px;
cursor: pointer;
}
.ais-MultiselectHierarchicalMenu-count {
background: var(--bs-blue);
color: white;
font-size: 0.75rem;
line-height: 1rem;
padding-right: 10px;
padding-left: 10px;
border-radius: 10px;
border: none;
cursor: pointer;
}
.ais-MultiselectHierarchicalMenu-toggle {
font-size: 30px;
color: var(--bs-blue);
vertical-align: middle;
/* margin-bottom: 1rem; */
background-color: transparent;
border: none;
padding: 0%;
cursor: pointer;
}
.ais-MultiselectHierarchicalMenu-list--child {
display: inline-block;
overflow-y: visible;
margin: 0;
padding: 0 0 0 4px;
width: 100%;
list-style: none;
}
.ais-MultiselectHierarchicalMenu-checkbox--child {
box-shadow: none;
outline: 1px solid black;
border-radius: 1px;
color: var(--bs-blue);
margin-right: 6px;
cursor: pointer;
}
.ais-MultiselectHierarchicalMenu-item--selected
.ais-MultiselectHierarchicalMenu-label {
font-weight: bold;
}
.ais-MultiselectHierarchicalMenu-item--child--selected
.ais-MultiselectHierarchicalMenu-label--child {
font-weight: bold;
}
.ais-MultiselectHierarchicalMenu-item--child--selected
.ais-MultiselectHierarchicalMenu-checkbox--child {
background-image: url("/check-solid.svg");
background-size: 0.75rem;
background-position: center;
background-repeat: no-repeat;
}
.ais-MultiselectHierarchicalMenu-item--child {
font-size: 1rem;
border-top: dashed 1px;
}
.ais-MultiselectHierarchicalMenu-label--child {
white-space: normal;
display: flex;
width: 100%;
align-items: center;
gap: 10px;
cursor: pointer;
}
.ais-MultiselectHierarchicalMenu-count--child {
background: var(--bs-blue);
color: white;
font-size: 0.75rem;
line-height: 1rem;
padding-right: 10px;
padding-left: 10px;
border-radius: 10px;
border: none;
cursor: pointer;
}
`
36 changes: 35 additions & 1 deletion components/search/bills/BillSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { SearchErrorBoundary } from "../SearchErrorBoundary"
import { useRouting } from "../useRouting"
import { BillHit } from "./BillHit"
import { useBillRefinements } from "./useBillRefinements"
import { useBillHierarchicalMenu } from "./useBillHierarchicalMenu"
import { SortBy, SortByWithConfigurationItem } from "../SortBy"
import { getServerConfig } from "../common"
import { useBillSort } from "./useBillSort"
Expand All @@ -30,6 +31,33 @@ const searchClient = new TypesenseInstantSearchAdapter({
}
}).searchClient

const extractLastSegmentOfRefinements = (items: any[]) => {
return items.map(item => {
console.log(item)
if (item.label != "topics.lvl1") return item
const newRefinements = item.refinements.map(
(refinement: { label: string }) => {
// Split the label to extract the last part of the hierarchy
const lastPartOfLabel = refinement.label.includes(">")
? refinement.label.split(" > ").pop()
: refinement.label

return {
...refinement,
// Update label to only show the last part
label: lastPartOfLabel
}
}
)

return {
...item,
label: "Tags",
refinements: newRefinements
}
})
}

export const BillSearch = () => {
const items = useBillSort()
const initialSortByValue = items[0].value
Expand Down Expand Up @@ -75,6 +103,7 @@ const Layout: FC<
React.PropsWithChildren<{ items: SortByWithConfigurationItem[] }>
> = ({ items }) => {
const refinements = useBillRefinements()
const hierarchicalMenu = useBillHierarchicalMenu()
const status = useSearchStatus()

return (
Expand All @@ -83,16 +112,21 @@ const Layout: FC<
<SearchBox placeholder="Search For Bills" className="mt-2 mb-3" />
</Row>
<Row>
{refinements.options}
<Col xs={3} lg={3}>
{hierarchicalMenu.options}
{refinements.options}
</Col>
<Col className="d-flex flex-column">
<RefinementRow>
<ResultCount className="flex-grow-1 m-1" />
<SortBy items={items} />
{hierarchicalMenu.show}
{refinements.show}
</RefinementRow>
<CurrentRefinements
className="mt-2 mb-2"
excludedAttributes={["nextHearingAt"]}
transformItems={extractLastSegmentOfRefinements}
/>
{status === "empty" ? (
<NoResults>
Expand Down
17 changes: 17 additions & 0 deletions components/search/bills/useBillHierarchicalMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useHierarchicalMenu } from "../useHierarchicalMenu"

export const useBillHierarchicalMenu = () => {
const baseProps = { limit: 500, searchable: true }
const propsList = [
{
attribute: "topics.lvl0",
...baseProps
},
{
attribute: "topics.lvl1",
...baseProps
}
]

return useHierarchicalMenu({ hierarchicalMenuProps: propsList })
}
4 changes: 3 additions & 1 deletion components/search/testimony/TestimonySearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ const Layout = () => {
/>
</Row>
<Row>
{refinements.options}
<Col xs={3} lg={3}>
{refinements.options}
</Col>
<Col className="d-flex flex-column">
<RefinementRow>
<ResultCount className="flex-grow-1 m-1" />
Expand Down
69 changes: 69 additions & 0 deletions components/search/useHierarchicalMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { useInstantSearch } from "react-instantsearch"
import { faFilter } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { useCallback, useState } from "react"
import styled from "styled-components"
import { useMediaQuery } from "usehooks-ts"
import { Button, Offcanvas } from "../bootstrap"
import { SearchContainer } from "./SearchContainer"
import { MultiselectHierarchicalMenu } from "./HierarchicalMenuWidget"
export const FilterButton = styled(Button)`
font-size: 1rem;
line-height: 1rem;
min-height: 2rem;
padding: 0.25rem 0.5rem 0.25rem 0.5rem;
align-self: flex-start;
`
const useHasRefinements = () => {
const { results } = useInstantSearch()
const refinements = results.getRefinements()
return refinements.length !== 0
}

export const useHierarchicalMenu = ({
hierarchicalMenuProps
}: {
hierarchicalMenuProps: any[]
}) => {
const inline = useMediaQuery("(min-width: 768px)")
const [show, setShow] = useState(false)
const handleClose = useCallback(() => setShow(false), [])
const handleOpen = useCallback(() => setShow(true), [])

const hierarchicalMenu = (
<>
<MultiselectHierarchicalMenu
attributes={[
hierarchicalMenuProps[0].attribute,
hierarchicalMenuProps[1].attribute
]}
/>
</>
)
const hasRefinements = useHasRefinements()

return {
options: inline ? (
<div>{hierarchicalMenu}</div>
) : (
<Offcanvas show={show} onHide={handleClose}>
<Offcanvas.Header closeButton>
<Offcanvas.Title>Filter</Offcanvas.Title>
</Offcanvas.Header>
<Offcanvas.Body>
<SearchContainer>{hierarchicalMenu}</SearchContainer>
</Offcanvas.Body>
</Offcanvas>
),
show: inline ? null : (
<FilterButton
variant="secondary"
active={show}
onClick={handleOpen}
className={hasRefinements ? "ais-FilterButton-has-refinements" : ""}
>
<FontAwesomeIcon icon={faFilter} /> Filter
</FilterButton>
)
}
}
16 changes: 7 additions & 9 deletions components/search/useRefinements.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { RefinementList, useInstantSearch } from "react-instantsearch"
import {
HierarchicalMenu,
HierarchicalMenuProps,
RefinementList,
useInstantSearch
} from "react-instantsearch"
import { faFilter } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { useCallback, useEffect, useState } from "react"
Expand All @@ -14,7 +19,6 @@ export const FilterButton = styled(Button)`
padding: 0.25rem 0.5rem 0.25rem 0.5rem;
align-self: flex-start;
`

const useHasRefinements = () => {
const { results } = useInstantSearch()
const refinements = results.getRefinements()
Expand All @@ -31,10 +35,6 @@ export const useRefinements = ({
const handleClose = useCallback(() => setShow(false), [])
const handleOpen = useCallback(() => setShow(true), [])

useEffect(() => {
if (inline) setShow(false)
}, [inline])

const refinements = (
<>
{refinementProps.map((p, i) => (
Expand All @@ -46,9 +46,7 @@ export const useRefinements = ({

return {
options: inline ? (
<Col xs={3} lg={3}>
{refinements}
</Col>
<div>{refinements}</div>
) : (
<Offcanvas show={show} onHide={handleClose}>
<Offcanvas.Header closeButton>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@
"eslint": "^8.7.0",
"eslint-config-next": "^14.0.4",
"eslint-config-prettier": "^8.3.0",
"firebase-admin": "^10",
"eslint-plugin-i18next": "^6.0.3",
"eslint-plugin-jsx-a11y": "^6.9.0",
"firebase-admin": "^10",
"firebase-tools": "^11.16.0",
"ini": "^1.3.5",
"inquirer": "^6.5.1",
Expand Down

0 comments on commit 491fb83

Please sign in to comment.