filter nouns by inflection pattern

This commit is contained in:
lingdocs 2022-03-28 14:24:58 +05:00
parent f22e6e7f5f
commit 3019d1cd39
4 changed files with 130 additions and 21 deletions

View File

@ -9,9 +9,63 @@ import {
InlinePs,
defaultTextOptions as opts,
} from "@lingdocs/pashto-inflector";
import { useState } from "react";
import { isFemNounEntry, isPattern1Entry, isPattern2Entry, isPattern3Entry, isPattern4Entry, isPattern5Entry, isPattern6FemEntry } from "../../lib/type-predicates";
function NPNounPicker({ onChange, noun, nouns }: { nouns: NounEntry[], noun: NounSelection | undefined, onChange: (p: NounSelection) => void }) {
const options = nouns.sort((a, b) => (a.p.localeCompare(b.p, "af-PS"))).map(makeSelectOption)
const filterOptions = [
{
label: "1",
value: "1",
},
{
label: "2",
value: "2",
},
{
label: "3",
value: "3",
},
{
label: "4",
value: "4",
},
{
label: "5",
value: "5",
},
{
label: "6",
value: "6",
},
];
type FilterPattern = "1" | "2" | "3" | "4" | "5" | "6";
function nounFilter(p: FilterPattern | undefined) {
return p === undefined
? () => true
: (p === "1")
? isPattern1Entry
: (p === "2")
? isPattern2Entry
: (p === "3")
? isPattern3Entry
: (p === "4")
? isPattern4Entry
: (p === "5")
? isPattern5Entry
: (p === "6")
? (n: NounEntry) => (isFemNounEntry(n) && isPattern6FemEntry(n))
: () => true;
}
function NPNounPicker({ onChange, noun, nouns, clearButton }: { nouns: NounEntry[], noun: NounSelection | undefined, onChange: (p: NounSelection) => void, clearButton?: JSX.Element }) {
const [patternFilter, setPatternFilter] = useState<FilterPattern | undefined>(undefined);
const [showFilter, setShowFilter] = useState<boolean>(false)
const options = nouns
.filter(nounFilter(patternFilter))
.sort((a, b) => (a.p.localeCompare(b.p, "af-PS")))
.map(makeSelectOption);
function onEntrySelect({ value }: { label: string, value: string }) {
const entry = nouns.find(n => n.ts.toString() === value);
if (!entry) {
@ -20,20 +74,46 @@ function NPNounPicker({ onChange, noun, nouns }: { nouns: NounEntry[], noun: Nou
}
onChange(makeNounSelection(entry));
}
function handleFilterClose() {
setPatternFilter(undefined);
setShowFilter(false);
}
return <div style={{ maxWidth: "225px", minWidth: "125px" }}>
{!(noun && noun.dynamicComplement) ? <Select
value={noun && noun.entry.ts.toString()}
// @ts-ignore
onChange={onEntrySelect}
className="mb-2"
// @ts-ignore
options={options}
isSearchable
// // @ts-ignore
placeholder={noun ? options.find(o => o.value === (noun.entry).ts.toString())?.label : "Select Noun..."}
{...zIndexProps}
/> : <div>
<div className="d-flex flex-row justify-content-between">
{clearButton}
{(!showFilter && !(noun?.dynamicComplement)) && <div className="text-right">
<button className="btn btn-sm btn-light mb-2 text-small" onClick={() => setShowFilter(true)}>
<i className="fas fa-filter fa-xs" />
</button>
</div>}
</div>
{showFilter && <div className="mb-2 text-center">
<div className="d-flex flex-row justify-content-between">
<div className="text-small mb-1">Filter by inflection pattern</div>
<div className="clickable" onClick={handleFilterClose}>X</div>
</div>
<ButtonSelect
options={filterOptions}
// @ts-ignore
value={patternFilter}
// @ts-ignore
handleChange={setPatternFilter}
/>
</div>}
{!(noun && noun.dynamicComplement) ? <div>
<Select
value={noun && noun.entry.ts.toString()}
// @ts-ignore
onChange={onEntrySelect}
className="mb-2"
// @ts-ignore
options={options}
isSearchable
// @ts-ignore
placeholder={noun ? options.find(o => o.value === (noun.entry).ts.toString())?.label : "Select Noun..."}
{...zIndexProps}
/>
</div> : <div>
{noun && <div>
<div className="mb-2">Included in Dyn. Compound:</div>
<div className="mb-3 text-center">

View File

@ -11,7 +11,12 @@ function makeParticipleSelection(verb: VerbEntry): ParticipleSelection {
};
}
function NPParticiplePicker({ onChange, participle, verbs }: { verbs: VerbEntry[], participle: ParticipleSelection | undefined, onChange: (p: ParticipleSelection) => void }) {
function NPParticiplePicker({ onChange, participle, verbs, clearButton }: {
verbs: VerbEntry[],
participle: ParticipleSelection | undefined,
onChange: (p: ParticipleSelection) => void,
clearButton: JSX.Element,
}) {
const options = verbs.map(makeSelectOption)
function onEntrySelect({ value }: { label: string, value: string }) {
const verb = verbs.find(v => v.entry.ts.toString() === value);
@ -22,6 +27,7 @@ function NPParticiplePicker({ onChange, participle, verbs }: { verbs: VerbEntry[
onChange(makeParticipleSelection(verb));
}
return <div style={{ maxWidth: "225px" }}>
{clearButton}
<Select
value={participle && participle.verb.entry.ts.toString()}
// @ts-ignore

View File

@ -41,6 +41,7 @@ function NPPicker({ np, onChange, counterPart, asObject }: {
}
}
const isDynamicComplement = np && np.type === "noun" && np.dynamicComplement;
const clearButton = <button className="btn btn-sm btn-light mb-2" onClick={handleClear}>X</button>;
return <div>
{!npType && <div className="text-center mt-3">
{npTypes.map((npt) => <div className="mb-2">
@ -54,16 +55,32 @@ function NPPicker({ np, onChange, counterPart, asObject }: {
</button>
</div>)}
</div>}
{(npType && !isDynamicComplement) && <button className="btn btn-sm btn-light mb-2" onClick={handleClear}>X</button>}
{(npType === "pronoun" && np?.type === "pronoun")
? <PronounPicker asObject={asObject} pronoun={np} onChange={onChange} />
? <PronounPicker
asObject={asObject}
pronoun={np}
onChange={onChange}
clearButton={clearButton}
/>
: npType === "noun"
? <NounPicker nouns={nouns} noun={(np && np.type === "noun") ? np : undefined} onChange={onChange} />
? <NounPicker
nouns={nouns}
noun={(np && np.type === "noun") ? np : undefined}
onChange={onChange}
clearButton={!isDynamicComplement ? clearButton : undefined}
/>
: npType === "participle"
? <ParticiplePicker verbs={verbs} participle={(np && np.type === "participle") ? np : undefined} onChange={onChange} />
? <ParticiplePicker
verbs={verbs}
participle={(np && np.type === "participle") ? np : undefined}
onChange={onChange}
clearButton={clearButton}
/>
: null
}
</div>;
}
// {(npType && !isDynamicComplement) && }
export default NPPicker;

View File

@ -55,7 +55,12 @@ function pickerStateToPerson(s: PickerState): T.Person {
+ (6 * s.col);
}
function NPPronounPicker({ onChange, pronoun, asObject }: { pronoun: PronounSelection, onChange: (p: PronounSelection) => void , asObject?: boolean }) {
function NPPronounPicker({ onChange, pronoun, asObject, clearButton }: {
pronoun: PronounSelection,
onChange: (p: PronounSelection) => void,
asObject?: boolean,
clearButton?: JSX.Element,
}) {
const [display, setDisplay] = useStickyState<"persons" | "p" | "e">("persons", "prounoun-picker-display");
const p = personToPickerState(pronoun.person);
@ -90,6 +95,7 @@ function NPPronounPicker({ onChange, pronoun, asObject }: { pronoun: PronounSele
const prs = labels(!!asObject)[display];
const pSpec = "near" in prs ? prs[pronoun.distance] : prs;
return <div style={{ maxWidth: "225px", minWidth: "125px", padding: 0 }}>
{clearButton}
<div className="d-flex flex-row justify-content-around mb-3">
<ButtonSelect
xSmall