import { CloseOutlined, EnterOutlined } from '@ant-design/icons'; import { Tour } from 'antd'; import { observer } from 'mobx-react-lite'; import React, { useState } from 'react'; import { connect } from 'react-redux'; import { useStore } from 'App/mstore'; import { assist as assistRoute, isRoute } from 'App/routes'; import { debounce } from 'App/utils'; import { addFilterByKeyAndValue as liveAddFilterByKeyAndValue, fetchFilterSearch as liveFetchFilterSearch, } from 'Duck/liveSearch'; import { addFilterByKeyAndValue, clearSearch, edit, fetchFilterSearch, } from 'Duck/search'; import { Icon, Input } from 'UI'; import FilterModal from 'Shared/Filters/FilterModal'; import OutsideClickDetectingDiv from '../OutsideClickDetectingDiv'; const ASSIST_ROUTE = assistRoute(); interface Props { fetchFilterSearch: (query: any) => void; addFilterByKeyAndValue: (key: string, value: string) => void; liveAddFilterByKeyAndValue: (key: string, value: string) => void; liveFetchFilterSearch: any; appliedFilter: any; edit: typeof edit; clearSearch: typeof clearSearch; setFocused?: (focused: boolean) => void; } function SessionSearchField(props: Props) { const isLive = isRoute(ASSIST_ROUTE, window.location.pathname) || window.location.pathname.includes('multiview'); const debounceFetchFilterSearch = React.useCallback( debounce( isLive ? props.liveFetchFilterSearch : props.fetchFilterSearch, 1000 ), [] ); const [showModal, setShowModal] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const onSearchChange = ({ target: { value } }: any) => { setSearchQuery(value); debounceFetchFilterSearch({ q: value }); }; const onAddFilter = (filter: any) => { isLive ? props.liveAddFilterByKeyAndValue(filter.key, filter.value) : props.addFilterByKeyAndValue(filter.key, filter.value); }; const onFocus = () => { setShowModal(true); props.setFocused?.(true); }; const onBlur = () => { setTimeout(() => { setShowModal(false); props.setFocused?.(false); }, 200); }; return (
{showModal && (
)}
); } const AiSearchField = observer( ({ edit, appliedFilter, clearSearch }: Props) => { const hasFilters = appliedFilter && appliedFilter.filters && appliedFilter.filters.size > 0; const { aiFiltersStore } = useStore(); const [searchQuery, setSearchQuery] = useState(''); const onSearchChange = ({ target: { value } }: any) => { setSearchQuery(value); }; const fetchResults = () => { if (searchQuery) { void aiFiltersStore.getSearchFilters(searchQuery); } }; const handleKeyDown = (event: any) => { if (event.key === 'Enter') { fetchResults(); } }; const clearAll = () => { clearSearch(); setSearchQuery(''); }; React.useEffect(() => { if (aiFiltersStore.filtersSetKey !== 0) { edit(aiFiltersStore.filters); } }, [aiFiltersStore.filters, aiFiltersStore.filtersSetKey]); return (
{hasFilters ? : }
) : null } /> ); } ); function AiSessionSearchField(props: Props) { const askTourKey = '__or__ask-tour'; const tabKey = '__or__tab'; const { aiFiltersStore } = useStore(); const isTourShown = localStorage.getItem(askTourKey) !== null; const [tab, setTab] = useState(localStorage.getItem(tabKey) || 'search'); const [touring, setTouring] = useState(!isTourShown); const [isFocused, setFocused] = React.useState(false); const askAiRef = React.useRef(null); const closeTour = () => { setTouring(false); localStorage.setItem(askTourKey, 'true'); }; const changeValue = (v?: string) => { const newTab = v ? v : tab !== 'ask' ? 'ask' : 'search'; setTab(newTab); localStorage.setItem(tabKey, newTab); }; const boxStyle = tab === 'ask' ? gradientBox : isFocused ? regularBoxFocused : regularBoxUnfocused; return (
{tab === 'ask' ? ( ) : ( )} Introducing Ask AI
), target: () => askAiRef.current, description: 'Easily find sessions with our AI search. Just enable Ask AI, type in your query naturally, and the AI will swiftly and precisely display relevant sessions.', nextButtonProps: { children: ( Ask AI ), onClick: () => { changeValue('ask'); closeTour(); }, }, }, ]} />
); } export const AskAiSwitchToggle = ({ enabled, setEnabled, loading, }: { enabled: boolean; loading: boolean; setEnabled: () => void; }) => { return (
setEnabled()} className={loading ? 'animate-bg-spin' : ''} style={{ position: 'relative', display: 'inline-block', height: 24, background: enabled ? 'linear-gradient(-25deg, #394eff, #3EAAAf, #3ccf65)' : 'rgb(170 170 170)', backgroundSize: loading ? '200% 200%' : 'unset', borderRadius: 100, cursor: 'pointer', transition: 'all 0.2s ease-in-out', border: 0, verticalAlign: 'middle', }} >
Ask AI
); }; export const gradientBox = { border: 'double 1.5px transparent', borderRadius: '100px', background: 'linear-gradient(#ffffff, #ffffff), linear-gradient(-45deg, #394eff, #3eaaaf, #3ccf65)', backgroundOrigin: 'border-box', backgroundSize: '200% 200%', backgroundClip: 'content-box, border-box', display: 'flex', gap: '0.25rem', alignItems: 'center', width: '100%', }; const regularBoxUnfocused = { borderRadius: '100px', border: 'solid 1.5px #BFBFBF', background: '#fffff', display: 'flex', gap: '0.25rem', alignItems: 'center', width: '100%', }; const regularBoxFocused = { borderRadius: '100px', border: 'solid 1.5px #394EFF', background: '#fffff', display: 'flex', gap: '0.25rem', alignItems: 'center', width: '100%', } export default connect( (state: any) => ({ appliedFilter: state.getIn(['search', 'instance']), }), { addFilterByKeyAndValue, fetchFilterSearch, liveFetchFilterSearch, liveAddFilterByKeyAndValue, edit, clearSearch, } )(observer(AiSessionSearchField));