filter nouns by inflection pattern
This commit is contained in:
parent
f22e6e7f5f
commit
3019d1cd39
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue