diff options
Diffstat (limited to 'src/client/views/newlightbox/RecommendationList/RecommendationList.tsx')
-rw-r--r-- | src/client/views/newlightbox/RecommendationList/RecommendationList.tsx | 295 |
1 files changed, 158 insertions, 137 deletions
diff --git a/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx b/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx index 9f3c32e4e..1d502b73f 100644 --- a/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx +++ b/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx @@ -1,74 +1,67 @@ -import { GrClose } from 'react-icons/gr'; -import { IRecommendation, Recommendation } from "../components"; -import './RecommendationList.scss'; +import { IconButton, Size, Type } from 'browndash-components'; import * as React from 'react'; -import { IRecommendationList } from "./utils"; -import { NewLightboxView } from '../NewLightboxView'; -import { DocCast, StrCast } from '../../../../fields/Types'; import { FaCaretDown, FaCaretUp } from 'react-icons/fa'; -import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc'; -import { IDocRequest, fetchKeywords, fetchRecommendations } from '../utils'; -import { IBounds } from '../ExploreView/utils'; +import { GrClose } from 'react-icons/gr'; +import { DocListCast, StrListCast } from '../../../../fields/Doc'; import { List } from '../../../../fields/List'; -import { Id } from '../../../../fields/FieldSymbols'; +import { StrCast } from '../../../../fields/Types'; import { LightboxView } from '../../LightboxView'; -import { IconButton, Size, Type } from 'browndash-components'; import { Colors } from '../../global/globalEnums'; +import { IBounds } from '../ExploreView/utils'; +import { NewLightboxView } from '../NewLightboxView'; +import { IRecommendation, Recommendation } from '../components'; +import { IDocRequest, fetchKeywords, fetchRecommendations } from '../utils'; +import './RecommendationList.scss'; +import { IRecommendationList } from './utils'; export const RecommendationList = (props: IRecommendationList) => { - const {loading, keywords} = props - const [loadingKeywords, setLoadingKeywords] = React.useState<boolean>(true) - const [showMore, setShowMore] = React.useState<boolean>(false) - const [keywordsLoc, setKeywordsLoc] = React.useState<string[]>([]) - const [update, setUpdate] = React.useState<boolean>(true) - const initialRecs: IRecommendation[] = [ - {loading: true}, - {loading: true}, - {loading: true}, - {loading: true}, - {loading: true} - ]; - const [recs, setRecs] = React.useState<IRecommendation[]>(initialRecs) + const { loading, keywords } = props; + const [loadingKeywords, setLoadingKeywords] = React.useState<boolean>(true); + const [showMore, setShowMore] = React.useState<boolean>(false); + const [keywordsLoc, setKeywordsLoc] = React.useState<string[]>([]); + const [update, setUpdate] = React.useState<boolean>(true); + const initialRecs: IRecommendation[] = [{ loading: true }, { loading: true }, { loading: true }, { loading: true }, { loading: true }]; + const [recs, setRecs] = React.useState<IRecommendation[]>(initialRecs); React.useEffect(() => { const getKeywords = async () => { - let text = StrCast(LightboxView.LightboxDoc?.text) - console.log('[1] fetching keywords') - const response = await fetchKeywords(text, 5, true) - console.log('[2] response:', response) + let text = StrCast(LightboxView.LightboxDoc?.text); + console.log('[1] fetching keywords'); + const response = await fetchKeywords(text, 5, true); + console.log('[2] response:', response); const kw = response.keywords; console.log(kw); NewLightboxView.SetKeywords(kw); if (LightboxView.LightboxDoc) { - console.log('setting keywords on doc') + console.log('setting keywords on doc'); LightboxView.LightboxDoc.keywords = new List<string>(kw); setKeywordsLoc(NewLightboxView.Keywords); } - setLoadingKeywords(false) - } - let keywordsList = StrListCast(LightboxView.LightboxDoc!.keywords) + setLoadingKeywords(false); + }; + let keywordsList = StrListCast(LightboxView.LightboxDoc!.keywords); if (!keywordsList || keywordsList.length < 2) { - setLoadingKeywords(true) - getKeywords() - setUpdate(!update) + setLoadingKeywords(true); + getKeywords(); + setUpdate(!update); } else { - setKeywordsLoc(keywordsList) - setLoadingKeywords(false) - setUpdate(!update) + setKeywordsLoc(keywordsList); + setLoadingKeywords(false); + setUpdate(!update); } - }, [NewLightboxView.LightboxDoc]) + }, [NewLightboxView.LightboxDoc]); - // terms: vannevar bush, information spaces, + // terms: vannevar bush, information spaces, React.useEffect(() => { const getRecommendations = async () => { - console.log('fetching recommendations') - let query = 'undefined' - if (keywordsLoc) query = keywordsLoc.join(',') - let src = StrCast(NewLightboxView.LightboxDoc?.text) - let dashDocs:IDocRequest[] = []; + console.log('fetching recommendations'); + let query = 'undefined'; + if (keywordsLoc) query = keywordsLoc.join(','); + let src = StrCast(NewLightboxView.LightboxDoc?.text); + let dashDocs: IDocRequest[] = []; // get linked docs - let linkedDocs = DocListCast(NewLightboxView.LightboxDoc?.links) - console.log("linked docs", linkedDocs) + let linkedDocs = DocListCast(NewLightboxView.LightboxDoc?.links); + console.log('linked docs', linkedDocs); // get context docs (docs that are also in the collection) // let contextDocs: Doc[] = DocListCast(DocCast(LightboxView.LightboxDoc?.context).data) // let docId = LightboxView.LightboxDoc && LightboxView.LightboxDoc[Id] @@ -83,114 +76,142 @@ export const RecommendationList = (props: IRecommendationList) => { // }) // } // }) - console.log("dash docs", dashDocs) + console.log('dash docs', dashDocs); if (query !== undefined) { - const response = await fetchRecommendations(src, query, [], true) - const num_recs = response.num_recommendations - const recs = response.recommendations - const keywords = response.keywords + const response = await fetchRecommendations(src, query, [], true); + const num_recs = response.num_recommendations; + const recs = response.recommendations; + const keywords = response.keywords; const response_bounds: IBounds = { - max_x: response.max_x, - max_y: response.max_y, - min_x: response.min_x, - min_y: response.min_y - } + max_x: response.max_x, + max_y: response.max_y, + min_x: response.min_x, + min_y: response.min_y, + }; // if (NewLightboxView.NewLightboxDoc) { // NewLightboxView.NewLightboxDoc.keywords = new List<string>(keywords); // setKeywordsLoc(NewLightboxView.Keywords); // } // console.log(response_bounds) - NewLightboxView.SetBounds(response_bounds) + NewLightboxView.SetBounds(response_bounds); const recommendations: IRecommendation[] = []; for (const key in recs) { - console.log(key) + console.log(key); const title = recs[key].title; - const url = recs[key].url - const type = recs[key].type - const text = recs[key].text - const transcript = recs[key].transcript - const previewUrl = recs[key].previewUrl - const embedding = recs[key].embedding - const distance = recs[key].distance - const source = recs[key].source - const related_concepts = recs[key].related_concepts - const docId = recs[key].doc_id - related_concepts.length >= 1 && recommendations.push({ - title: title, - data: url, - type: type, - text: text, - transcript: transcript, - previewUrl: previewUrl, - embedding: embedding, - distance: Math.round(distance * 100) / 100, - source: source, - related_concepts: related_concepts, - docId: docId - }) + const url = recs[key].url; + const type = recs[key].type; + const text = recs[key].text; + const transcript = recs[key].transcript; + const previewUrl = recs[key].previewUrl; + const embedding = recs[key].embedding; + const distance = recs[key].distance; + const source = recs[key].source; + const related_concepts = recs[key].related_concepts; + const docId = recs[key].doc_id; + related_concepts.length >= 1 && + recommendations.push({ + title: title, + data: url, + type: type, + text: text, + transcript: transcript, + previewUrl: previewUrl, + embedding: embedding, + distance: Math.round(distance * 100) / 100, + source: source, + related_concepts: related_concepts, + docId: docId, + }); } recommendations.sort((a, b) => { if (a.distance && b.distance) { - return a.distance - b.distance - } else return 0 - }) - console.log("[rec]: ", recommendations) - NewLightboxView.SetRecs(recommendations) - setRecs(recommendations) + return a.distance - b.distance; + } else return 0; + }); + console.log('[rec]: ', recommendations); + NewLightboxView.SetRecs(recommendations); + setRecs(recommendations); } - } + }; getRecommendations(); - }, [update]) - - + }, [update]); - return <div className={`recommendationlist-container`} onPointerDown={(e) => {e.stopPropagation()}}> - <div className={`header`}> - <div className={`title`}> - Recommendations - </div> - {NewLightboxView.LightboxDoc && <div style={{fontSize: 10}}> - The recommendations are produced based on the text in the document <b><u>{StrCast(NewLightboxView.LightboxDoc.title)}</u></b>. The following keywords are used to fetch the recommendations. - </div>} - <div className={`lb-label`}>Keywords</div> - {loadingKeywords ? <div className={`keywords`}> - <div className={`keyword ${loadingKeywords && 'loading'}`}/> - <div className={`keyword ${loadingKeywords && 'loading'}`}/> - <div className={`keyword ${loadingKeywords && 'loading'}`}/> - <div className={`keyword ${loadingKeywords && 'loading'}`}/> + return ( + <div + className={`recommendationlist-container`} + onPointerDown={e => { + e.stopPropagation(); + }}> + <div className={`header`}> + <div className={`title`}>Recommendations</div> + {NewLightboxView.LightboxDoc && ( + <div style={{ fontSize: 10 }}> + The recommendations are produced based on the text in the document{' '} + <b> + <u>{StrCast(NewLightboxView.LightboxDoc.title)}</u> + </b> + . The following keywords are used to fetch the recommendations. </div> - : - <div className={`keywords`}> - {keywordsLoc && keywordsLoc.map((word, ind) => { - return <div className={`keyword`}> - {word} - <IconButton type={Type.PRIM} size={Size.XSMALL} color={Colors.DARK_GRAY} icon={<GrClose/>} onClick={() => { - let kw = keywordsLoc - kw.splice(ind) - NewLightboxView.SetKeywords(kw) - }}/> + )} + <div className={`lb-label`}>Keywords</div> + {loadingKeywords ? ( + <div className={`keywords`}> + <div className={`keyword ${loadingKeywords && 'loading'}`} /> + <div className={`keyword ${loadingKeywords && 'loading'}`} /> + <div className={`keyword ${loadingKeywords && 'loading'}`} /> + <div className={`keyword ${loadingKeywords && 'loading'}`} /> </div> - })} - </div> - } - {!showMore ? - <div className={`lb-caret`} onClick={() => {setShowMore(true)}}> - More <FaCaretDown/> + ) : ( + <div className={`keywords`}> + {keywordsLoc && + keywordsLoc.map((word, ind) => { + return ( + <div className={`keyword`}> + {word} + <IconButton + type={Type.PRIM} + size={Size.XSMALL} + color={Colors.DARK_GRAY} + icon={<GrClose />} + onClick={() => { + let kw = keywordsLoc; + kw.splice(ind); + NewLightboxView.SetKeywords(kw); + }} + /> + </div> + ); + })} + </div> + )} + {!showMore ? ( + <div + className={`lb-caret`} + onClick={() => { + setShowMore(true); + }}> + More <FaCaretDown /> + </div> + ) : ( + <div className={`more`}> + <div + className={`lb-caret`} + onClick={() => { + setShowMore(false); + }}> + Less <FaCaretUp /> + </div> + <div className={`lb-label`}>Type</div> + <div className={`lb-label`}>Sources</div> + </div> + )} </div> - : - <div className={`more`}> - <div className={`lb-caret`} onClick={() => {setShowMore(false)}}> - Less <FaCaretUp/> - </div> - <div className={`lb-label`}>Type</div> - <div className={`lb-label`}>Sources</div> + <div className={`recommendations`}> + {recs && + recs.map((rec: IRecommendation) => { + return <Recommendation {...rec} />; + })} </div> - } - </div> - <div className={`recommendations`}> - {recs && recs.map((rec: IRecommendation) => { - return <Recommendation {...rec} /> - })} </div> - </div> -}
\ No newline at end of file + ); +}; |