Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion client/.env.test
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
REACT_APP_API_BASE_URL=https://endpoint.yale.edu/
REACT_APP_FACETS_API_BASE_URL=https://endpoint2.collections.yale.edu/
REACT_APP_CMS_API_BASE_URL=https://endpoint.pantheonsite.io/jsonapi/
REACT_APP_WIKIDATA_IMAGE_PATHNAME=https://commons.wikimedia.org/test/Special:Filepath/
REACT_APP_LUX_WIKIDATA_MANIFEST_PREFIX=https://view.endpoint.yale.edu/uv3/?manifest=https://manifests.endpoint.yale.edu/test/manifest/
Expand Down
1 change: 1 addition & 0 deletions client/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ All notable changes to this project will be documented in this file.

- Added Objects and Works overlay button to objects/works included section ([#559](https://github.com/project-lux/lux-frontend/issues/559)).
- Added support for Collections Created, Published, or Influenced By on P&G pages ([#837](https://github.com/project-lux/lux-frontend/issues/837)).
- Added AI Search components ([#836](https://github.com/project-lux/lux-frontend/issues/836)).

### Changed

Expand Down
4 changes: 2 additions & 2 deletions client/src/config/advancedSearch/inputTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export const dimensions: Array<string> = [

export const recordTypes: Record<string, Record<string, string>> = {
agent: {
person: 'Person',
group: 'Group',
Person: 'Person',
Group: 'Group',
},
item: {
HumanMadeObject: 'Physical Object',
Expand Down
1 change: 1 addition & 0 deletions client/src/features/advancedSearch/ToggleSearchButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const ToggleButton: React.FC<IToggleSearchButton> = ({
translate({
query: searchString,
scope,
isAiSearch: false,
onSuccess: (translatedString) => {
dispatch(changeCurrentSearchState({ value: 'advanced' }))
const translatedObject = JSON.parse(translatedString)
Expand Down
3 changes: 2 additions & 1 deletion client/src/features/results/EventResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ const EventResults: React.FC<IProps> = ({ searchResponse, isMobile }) => {
const pageParam = `${paramPrefix}p`
const page: any = queryString.has(pageParam) ? queryString.get(pageParam) : 1
const sort = queryString.get(`${tab}Sort`)
const hasSimpleSearchQuery = queryString.has('sq')
const hasSimpleSearchQuery =
queryString.has('sq') && !queryString.has('aiSearch')
const view: string = queryString.has('view')
? (queryString.get('view') as string)
: 'list'
Expand Down
4 changes: 2 additions & 2 deletions client/src/features/results/ObjectResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ const ObjectResults: React.FC<IProps> = ({ searchResponse, isMobile }) => {
const view: string = queryString.has('view')
? (queryString.get('view') as string)
: 'list'
const hasSimpleSearchQuery = queryString.has('sq')

const hasSimpleSearchQuery =
queryString.has('sq') && !queryString.has('aiSearch')
const { data, isFetching, isSuccess, isError, error, isLoading, status } =
searchResponse

Expand Down
4 changes: 3 additions & 1 deletion client/src/features/results/ResultsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const ResultsPage: React.FC = () => {
const urlParams = new URLSearchParams(search)
const fromLandingPage = isFromLandingPage(state as { [key: string]: boolean })
// Check if current tab q exist
const hasSimpleSearchQuery = urlParams.has('sq')
const hasSimpleSearchQuery = urlParams.has('sq') && !urlParams.has('aiSearch')
// Setting as empty strings
const queryString = urlParams.get('q') || ''
const queryTab = urlParams.get('qt') || tab
Expand All @@ -110,6 +110,7 @@ const ResultsPage: React.FC = () => {
const rnd = urlParams.get('rnd') || undefined
const isSwitchToSimpleSearch =
urlParams.get('fromAdvanced') === 'true' || false
const isAiSearch = urlParams.get('aiSearch') === 'true' || false
const facetSearchString = urlParams.get(`${paramPrefix}f`) || null
let searchStringWithFacets = ''

Expand All @@ -136,6 +137,7 @@ const ResultsPage: React.FC = () => {
const searchResponse = useSearchQuery(
{
q: searchStringWithFacets,
isAiSearch,
filterResults,
page,
tab,
Expand Down
1 change: 1 addition & 0 deletions client/src/features/search/AdvancedSearchButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const AdvancedSearchButton: React.FC<IProps> = ({ setIsError, id }) => {
}
translate({
query: searchString,
isAiSearch: false,
scope: searchScope[entityType],
onSuccess: (translatedString) => {
const urlParams = new URLSearchParams()
Expand Down
49 changes: 45 additions & 4 deletions client/src/features/search/SearchBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useNavigate, useLocation, useParams } from 'react-router-dom'
import styled from 'styled-components'

import { useAppDispatch, useAppSelector } from '../../app/hooks'
import { searchScope } from '../../config/searchTypes'
import { scopeToTabTranslation, searchScope } from '../../config/searchTypes'
import { checkForStopWords, translate } from '../../lib/util/translate'
import {
addSimpleSearchInput,
Expand Down Expand Up @@ -43,6 +43,7 @@ const StyledSearchBox = styled.div`
}

.submitButton {
border: none;
background-color: ${theme.color.white};
border-radius: 0 ${theme.searchBox.borderRadiusMobile}
${theme.searchBox.borderRadiusMobile} 0;
Expand All @@ -56,6 +57,19 @@ const StyledSearchBox = styled.div`
${theme.searchBox.borderRadius} 0;
}
}

.submitAiButton {
border: none;
background-color: ${theme.color.white};
height: 72px;
font-size: inherit;
}

.submitSearch {
&:hover {
background-color: ${theme.color.lightGray};
}
}
`

const SearchBox: React.FC<{
Expand All @@ -74,6 +88,7 @@ const SearchBox: React.FC<{
isSearchOpen = false,
}) => {
const [isLoading, setIsLoading] = useState(false)
const [isAiSearch, setIsAiSearch] = useState<boolean>(false)
const currentState = useAppSelector(
(state) => state.simpleSearch as ISimpleSearchState,
)
Expand Down Expand Up @@ -122,23 +137,34 @@ const SearchBox: React.FC<{
const valueToSubmit = checkForStopWords(currentState.value!)
translate({
query: valueToSubmit,
isAiSearch,
scope: searchScope[tab],
onSuccess: (translatedString) => {
let newTab = tab
if (isAiSearch) {
const jsonTranslatedString = JSON.parse(translatedString)
newTab = scopeToTabTranslation[jsonTranslatedString._scope]
}
const newUrlParams = new URLSearchParams()
const query = JSON.parse(translatedString)
delete query._scope
newUrlParams.set('q', JSON.stringify(query))
newUrlParams.set('sq', valueToSubmit)
newUrlParams.set('aiSearch', isAiSearch ? 'true' : 'false')
if (closeSearchBox) {
closeSearchBox()
}
inputRef.current!.value = ''
setIsError(false)
setIsLoading(false)
pushClientEvent('Search Button', 'Submit', 'Simple Search')
pushClientEvent(
'Search Button',
'Submit',
isAiSearch ? 'AI Search' : 'Simple Search',
)
navigate(
{
pathname: `/view/results/${tab}`,
pathname: `/view/results/${newTab}`,
search: `${newUrlParams.toString()}`,
},
{
Expand Down Expand Up @@ -196,8 +222,23 @@ const SearchBox: React.FC<{
<button
disabled={!validateInput()}
type="submit"
className="btn submitButton"
className="btn submitAiButton submitSearch"
aria-label="submit AI search input"
onClick={() => setIsAiSearch(true)}
data-testid={`${id}-ai-search-submit-button`}
>
{isLoading ? (
<LoadingSpinner />
) : (
<i className="bi bi-stars" />
)}
</button>
<button
disabled={!validateInput()}
type="submit"
className="btn submitButton submitSearch"
aria-label="submit search input"
onClick={() => setIsAiSearch(false)}
data-testid={`${id}-search-submit-button`}
>
{isLoading ? (
Expand Down
5 changes: 4 additions & 1 deletion client/src/lib/util/translate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { fetchWithToken } from './fetchWithToken'

interface ITranslateParameters {
query: string
isAiSearch: boolean
scope: string
onSuccess: (translatedString: string) => void
onError: () => void
Expand All @@ -12,16 +13,18 @@ interface ITranslateParameters {

export function translate({
query,
isAiSearch,
scope,
onSuccess,
onError,
onLoading,
}: ITranslateParameters): void {
const urlParams = new URLSearchParams()
urlParams.set('q', query)
const updatedScope = isAiSearch ? '' : `/${scope}`
onLoading()
fetchWithToken(
`${getDataApiBaseUrl()}api/translate/${scope}?${urlParams.toString()}`,
`${getDataApiBaseUrl()}api/${isAiSearch ? 'ai-' : ''}translate${updatedScope}?${urlParams.toString()}`,
)
.then((response) => {
if (response.ok) {
Expand Down
1 change: 1 addition & 0 deletions client/src/redux/api/ml_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export const mlApi: any = createApi({

let scope = ''
if (!isUndefined(tab)) {
// If the search is an AI search, do not set a scope
scope = searchScope[tab]
}
if (!isUndefined(subTab)) {
Expand Down
7 changes: 6 additions & 1 deletion client/src/types/IMlApiParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ export interface ISearchParams {
facetNames?: string
sort?: string
rnd?: string // sequence number for random shuffle queries
[key: string]: string | number | { [key: string]: string } | undefined
[key: string]:
| string
| number
| boolean
| { [key: string]: string }
| undefined
}

export interface IItemParams {
Expand Down
1 change: 1 addition & 0 deletions server/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const numInstances = getInt(process.env.NUM_INSTANCES) || -1

export const dataApiBaseUrl = getString(process.env.DATA_API_BASE_URL)
export const cmsApiBaseUrl = getString(process.env.CMS_API_BASE_URL)

export const wikidataImagePathname = getString(
process.env.WIKIDATA_IMAGE_PATHNAME,
)
Expand Down