-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Enhancement #544] Simplify FTS results rendering.
Do not load full term for each result, support all newly added fields.
- Loading branch information
Showing
5 changed files
with
102 additions
and
231 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,150 +1,63 @@ | ||
import * as React from "react"; | ||
import { injectIntl } from "react-intl"; | ||
import withI18n, { HasI18n } from "../../hoc/withI18n"; | ||
import VocabularyUtils, { IRI } from "../../../util/VocabularyUtils"; | ||
import AssetLink from "../../misc/AssetLink"; | ||
import Term from "../../../model/Term"; | ||
import { connect } from "react-redux"; | ||
import { ThunkDispatch } from "../../../util/Types"; | ||
import { loadTermByIri } from "../../../action/AsyncActions"; | ||
import { useSelector } from "react-redux"; | ||
import { SearchResultItem } from "./SearchResults"; | ||
import AssetLabel from "../../misc/AssetLabel"; | ||
import AssetFactory from "../../../util/AssetFactory"; | ||
import TermItState from "../../../model/TermItState"; | ||
import FTSMatch from "./FTSMatch"; | ||
import TermBadge from "../../badge/TermBadge"; | ||
import { getTermPath } from "../../term/TermLink"; | ||
import User from "../../../model/User"; | ||
import { getLocalized } from "../../../model/MultilingualString"; | ||
import { getShortLocale } from "../../../util/IntlUtil"; | ||
import TermStateBadge from "../../term/state/TermStateBadge"; | ||
import { useI18n } from "../../hook/useI18n"; | ||
import { getResultDescription } from "./VocabularyResultItem"; | ||
|
||
interface TermResultItemOwnProps { | ||
interface TermResultItemProps { | ||
result: SearchResultItem; | ||
} | ||
|
||
interface TermResultItemDispatchProps { | ||
loadTerm: (termIri: IRI) => Promise<Term | null>; | ||
} | ||
|
||
interface TermResultItemStateProps { | ||
user: User; | ||
} | ||
|
||
interface TermResultItemProps | ||
extends TermResultItemOwnProps, | ||
TermResultItemDispatchProps, | ||
TermResultItemStateProps, | ||
HasI18n {} | ||
|
||
interface TermResultItemState { | ||
text: string | undefined; | ||
} | ||
|
||
export class TermResultItem extends React.Component< | ||
TermResultItemProps, | ||
TermResultItemState | ||
> { | ||
constructor(props: TermResultItemProps) { | ||
super(props); | ||
this.state = { | ||
text: undefined, | ||
}; | ||
} | ||
const TermResultItem: React.FC<TermResultItemProps> = ({ result }) => { | ||
const { i18n } = useI18n(); | ||
const user = useSelector((state: TermItState) => state.user); | ||
|
||
public componentDidMount(): void { | ||
const indexOfDefinition = this.getIndexOf("definition"); | ||
if (indexOfDefinition < 0) { | ||
const iri = VocabularyUtils.create(this.props.result.iri); | ||
this.props.loadTerm(iri).then((term) => { | ||
if (term) { | ||
this.setState({ | ||
text: term!.definition | ||
? getLocalized( | ||
term!.definition, | ||
getShortLocale(this.props.locale) | ||
) | ||
: getLocalized( | ||
term!.scopeNote, | ||
getShortLocale(this.props.locale) | ||
), | ||
}); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
private getIndexOf(field: string) { | ||
return this.props.result.snippetFields.indexOf(field); | ||
} | ||
|
||
public render() { | ||
const i18n = this.props.i18n; | ||
const result = this.props.result; | ||
const t = { | ||
iri: result.iri, | ||
label: ( | ||
<> | ||
<span className="search-result-title">{result.label}</span> | ||
| ||
{this.props.result.vocabulary ? ( | ||
<> | ||
{i18n("search.results.vocabulary.from")} | ||
<AssetLabel iri={result.vocabulary!.iri} /> | ||
</> | ||
) : ( | ||
<></> | ||
)} | ||
</> | ||
), | ||
}; | ||
|
||
let text; | ||
if (this.getIndexOf("definition") > -1) { | ||
text = result.snippets[this.getIndexOf("definition")]; | ||
} else { | ||
text = this.state.text; | ||
} | ||
|
||
if (text && text!.length > 200) { | ||
text = text!.substring(0, 200) + " ..."; | ||
} | ||
|
||
const asset = AssetFactory.createAsset(result); | ||
return ( | ||
const t = { | ||
iri: result.iri, | ||
label: ( | ||
<> | ||
<TermBadge className="search-result-badge" /> | ||
<TermStateBadge state={result.state} /> | ||
<AssetLink | ||
asset={t} | ||
path={getTermPath(asset as Term, this.props.user)} | ||
tooltip={i18n("asset.link.tooltip")} | ||
/> | ||
<br /> | ||
<span className="search-result-snippet"> | ||
{this.getIndexOf("definition") > -1 ? ( | ||
<FTSMatch match={text || ""} /> | ||
) : ( | ||
text | ||
)} | ||
</span> | ||
<span className="search-result-title">{result.label}</span> | ||
| ||
{result.vocabulary ? ( | ||
<> | ||
{i18n("search.results.vocabulary.from")} | ||
<AssetLabel iri={result.vocabulary!.iri} /> | ||
</> | ||
) : ( | ||
<></> | ||
)} | ||
</> | ||
); | ||
} | ||
} | ||
|
||
export default connect< | ||
TermResultItemStateProps, | ||
TermResultItemDispatchProps, | ||
TermResultItemOwnProps, | ||
TermItState | ||
>( | ||
(state: TermItState) => { | ||
return { user: state.user }; | ||
}, | ||
(dispatch: ThunkDispatch) => { | ||
return { | ||
loadTerm: (termIri: IRI) => dispatch(loadTermByIri(termIri)), | ||
}; | ||
} | ||
)(injectIntl(withI18n(TermResultItem))); | ||
), | ||
}; | ||
const fields = ["definition", "scopeNote"]; | ||
|
||
const description = getResultDescription(result, fields); | ||
|
||
const asset = AssetFactory.createAsset(result); | ||
return ( | ||
<> | ||
<TermBadge className="search-result-badge" /> | ||
<TermStateBadge state={result.state} /> | ||
<AssetLink | ||
asset={t} | ||
path={getTermPath(asset as Term, user)} | ||
tooltip={i18n("asset.link.tooltip")} | ||
/> | ||
<br /> | ||
<span className="search-result-snippet"> | ||
<FTSMatch match={description} /> | ||
</span> | ||
</> | ||
); | ||
}; | ||
|
||
export default TermResultItem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,110 +1,65 @@ | ||
import * as React from "react"; | ||
import { injectIntl } from "react-intl"; | ||
import withI18n, { HasI18n } from "../../hoc/withI18n"; | ||
import VocabularyUtils, { IRI } from "../../../util/VocabularyUtils"; | ||
import { connect } from "react-redux"; | ||
import { ThunkDispatch } from "../../../util/Types"; | ||
import { SearchResultItem } from "./SearchResults"; | ||
import TermItState from "../../../model/TermItState"; | ||
import FTSMatch from "./FTSMatch"; | ||
import { getRdfsResource } from "../../../action/AsyncActions"; | ||
import RdfsResource from "../../../model/RdfsResource"; | ||
import Vocabulary from "../../../model/Vocabulary"; | ||
import VocabularyLink from "../../vocabulary/VocabularyLink"; | ||
import AssetFactory from "../../../util/AssetFactory"; | ||
import VocabularyBadge from "../../badge/VocabularyBadge"; | ||
import { getLocalized } from "../../../model/MultilingualString"; | ||
import { getShortLocale } from "../../../util/IntlUtil"; | ||
|
||
interface VocabularyResultItemOwnProps { | ||
interface VocabularyResultItemProps { | ||
result: SearchResultItem; | ||
} | ||
|
||
interface VocabularyResultItemDispatchProps { | ||
getResource: (iri: IRI) => Promise<RdfsResource | undefined>; | ||
export function getSnippetFieldIndex( | ||
result: SearchResultItem, | ||
fieldName: string | ||
) { | ||
return result.snippetFields.indexOf(fieldName); | ||
} | ||
|
||
interface VocabularyResultItemStateProps {} | ||
|
||
interface VocabularyResultItemProps | ||
extends VocabularyResultItemOwnProps, | ||
VocabularyResultItemDispatchProps, | ||
VocabularyResultItemStateProps, | ||
HasI18n {} | ||
|
||
interface VocabularyResultItemState { | ||
comment?: string | null; | ||
} | ||
|
||
export class VocabularyResultItem extends React.Component< | ||
VocabularyResultItemProps, | ||
VocabularyResultItemState | ||
> { | ||
constructor(props: VocabularyResultItemProps) { | ||
super(props); | ||
this.state = { | ||
comment: null, | ||
}; | ||
} | ||
|
||
public componentDidMount(): void { | ||
const indexOfComment = this.getIndexOf("comment"); | ||
if (indexOfComment < 0) { | ||
const iri = VocabularyUtils.create(this.props.result.iri); | ||
this.props.getResource(iri).then((resource) => { | ||
if (resource) { | ||
this.setState({ | ||
comment: getLocalized( | ||
resource.comment, | ||
getShortLocale(this.props.locale) | ||
), | ||
}); | ||
} | ||
}); | ||
export function getResultDescription( | ||
result: SearchResultItem, | ||
fieldNames: string[] | ||
) { | ||
let snippetFieldIndex = -1; | ||
for (let i = 0; i < fieldNames.length; i++) { | ||
snippetFieldIndex = getSnippetFieldIndex(result, fieldNames[i]); | ||
if (snippetFieldIndex >= 0) { | ||
break; | ||
} | ||
} | ||
|
||
private getIndexOf(field: string) { | ||
return this.props.result.snippetFields.indexOf(field); | ||
let text; | ||
if (snippetFieldIndex >= 0) { | ||
text = result.snippets[snippetFieldIndex]; | ||
} else { | ||
text = result.description; | ||
} | ||
|
||
public render() { | ||
let text; | ||
if (this.getIndexOf("comment") > -1) { | ||
text = this.props.result.snippets[this.getIndexOf("comment")]; | ||
} else { | ||
text = this.state.comment || ""; | ||
} | ||
|
||
if (text && text!.length > 200) { | ||
text = text!.substring(0, 200) + " ..."; | ||
} | ||
|
||
const res = this.props.result; | ||
return ( | ||
<> | ||
<VocabularyBadge className="search-result-badge" /> | ||
<span className="search-result-title"> | ||
<VocabularyLink | ||
vocabulary={AssetFactory.createAsset(res) as Vocabulary} | ||
/> | ||
</span> | ||
<br /> | ||
<span className="search-result-snippet"> | ||
<FTSMatch match={text || ""} /> | ||
</span> | ||
</> | ||
); | ||
if (text && text!.length > 200) { | ||
text = text!.substring(0, 200) + " ..."; | ||
} | ||
return text || ""; | ||
} | ||
|
||
export default connect< | ||
VocabularyResultItemStateProps, | ||
VocabularyResultItemDispatchProps, | ||
VocabularyResultItemOwnProps, | ||
TermItState | ||
>(undefined, (dispatch: ThunkDispatch) => { | ||
return { | ||
getResource: (iri: IRI) => dispatch(getRdfsResource(iri)), | ||
}; | ||
})(injectIntl(withI18n(VocabularyResultItem))); | ||
const VocabularyResultItem: React.FC<VocabularyResultItemProps> = ({ | ||
result, | ||
}) => { | ||
const description = getResultDescription(result, ["description"]); | ||
|
||
return ( | ||
<> | ||
<VocabularyBadge className="search-result-badge" /> | ||
<span className="search-result-title"> | ||
<VocabularyLink | ||
vocabulary={AssetFactory.createAsset(result) as Vocabulary} | ||
/> | ||
</span> | ||
<br /> | ||
<span className="search-result-snippet"> | ||
<FTSMatch match={description} /> | ||
</span> | ||
</> | ||
); | ||
}; | ||
|
||
export default VocabularyResultItem; |
Oops, something went wrong.