filter nouns by inflection pattern
This commit is contained in:
parent
f22e6e7f5f
commit
3019d1cd39
|
@ -9,9 +9,63 @@ import {
|
||||||
InlinePs,
|
InlinePs,
|
||||||
defaultTextOptions as opts,
|
defaultTextOptions as opts,
|
||||||
} from "@lingdocs/pashto-inflector";
|
} 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 filterOptions = [
|
||||||
const options = nouns.sort((a, b) => (a.p.localeCompare(b.p, "af-PS"))).map(makeSelectOption)
|
{
|
||||||
|
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 }) {
|
function onEntrySelect({ value }: { label: string, value: string }) {
|
||||||
const entry = nouns.find(n => n.ts.toString() === value);
|
const entry = nouns.find(n => n.ts.toString() === value);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
|
@ -20,8 +74,34 @@ function NPNounPicker({ onChange, noun, nouns }: { nouns: NounEntry[], noun: Nou
|
||||||
}
|
}
|
||||||
onChange(makeNounSelection(entry));
|
onChange(makeNounSelection(entry));
|
||||||
}
|
}
|
||||||
|
function handleFilterClose() {
|
||||||
|
setPatternFilter(undefined);
|
||||||
|
setShowFilter(false);
|
||||||
|
}
|
||||||
return <div style={{ maxWidth: "225px", minWidth: "125px" }}>
|
return <div style={{ maxWidth: "225px", minWidth: "125px" }}>
|
||||||
{!(noun && noun.dynamicComplement) ? <Select
|
<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()}
|
value={noun && noun.entry.ts.toString()}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
onChange={onEntrySelect}
|
onChange={onEntrySelect}
|
||||||
|
@ -29,11 +109,11 @@ function NPNounPicker({ onChange, noun, nouns }: { nouns: NounEntry[], noun: Nou
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
options={options}
|
options={options}
|
||||||
isSearchable
|
isSearchable
|
||||||
// // @ts-ignore
|
// @ts-ignore
|
||||||
|
|
||||||
placeholder={noun ? options.find(o => o.value === (noun.entry).ts.toString())?.label : "Select Noun..."}
|
placeholder={noun ? options.find(o => o.value === (noun.entry).ts.toString())?.label : "Select Noun..."}
|
||||||
{...zIndexProps}
|
{...zIndexProps}
|
||||||
/> : <div>
|
/>
|
||||||
|
</div> : <div>
|
||||||
{noun && <div>
|
{noun && <div>
|
||||||
<div className="mb-2">Included in Dyn. Compound:</div>
|
<div className="mb-2">Included in Dyn. Compound:</div>
|
||||||
<div className="mb-3 text-center">
|
<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)
|
const options = verbs.map(makeSelectOption)
|
||||||
function onEntrySelect({ value }: { label: string, value: string }) {
|
function onEntrySelect({ value }: { label: string, value: string }) {
|
||||||
const verb = verbs.find(v => v.entry.ts.toString() === value);
|
const verb = verbs.find(v => v.entry.ts.toString() === value);
|
||||||
|
@ -22,6 +27,7 @@ function NPParticiplePicker({ onChange, participle, verbs }: { verbs: VerbEntry[
|
||||||
onChange(makeParticipleSelection(verb));
|
onChange(makeParticipleSelection(verb));
|
||||||
}
|
}
|
||||||
return <div style={{ maxWidth: "225px" }}>
|
return <div style={{ maxWidth: "225px" }}>
|
||||||
|
{clearButton}
|
||||||
<Select
|
<Select
|
||||||
value={participle && participle.verb.entry.ts.toString()}
|
value={participle && participle.verb.entry.ts.toString()}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
|
@ -41,6 +41,7 @@ function NPPicker({ np, onChange, counterPart, asObject }: {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const isDynamicComplement = np && np.type === "noun" && np.dynamicComplement;
|
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>
|
return <div>
|
||||||
{!npType && <div className="text-center mt-3">
|
{!npType && <div className="text-center mt-3">
|
||||||
{npTypes.map((npt) => <div className="mb-2">
|
{npTypes.map((npt) => <div className="mb-2">
|
||||||
|
@ -54,16 +55,32 @@ function NPPicker({ np, onChange, counterPart, asObject }: {
|
||||||
</button>
|
</button>
|
||||||
</div>)}
|
</div>)}
|
||||||
</div>}
|
</div>}
|
||||||
{(npType && !isDynamicComplement) && <button className="btn btn-sm btn-light mb-2" onClick={handleClear}>X</button>}
|
|
||||||
{(npType === "pronoun" && np?.type === "pronoun")
|
{(npType === "pronoun" && np?.type === "pronoun")
|
||||||
? <PronounPicker asObject={asObject} pronoun={np} onChange={onChange} />
|
? <PronounPicker
|
||||||
|
asObject={asObject}
|
||||||
|
pronoun={np}
|
||||||
|
onChange={onChange}
|
||||||
|
clearButton={clearButton}
|
||||||
|
/>
|
||||||
: npType === "noun"
|
: 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"
|
: 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
|
: null
|
||||||
}
|
}
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// {(npType && !isDynamicComplement) && }
|
||||||
|
|
||||||
export default NPPicker;
|
export default NPPicker;
|
|
@ -55,7 +55,12 @@ function pickerStateToPerson(s: PickerState): T.Person {
|
||||||
+ (6 * s.col);
|
+ (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 [display, setDisplay] = useStickyState<"persons" | "p" | "e">("persons", "prounoun-picker-display");
|
||||||
|
|
||||||
const p = personToPickerState(pronoun.person);
|
const p = personToPickerState(pronoun.person);
|
||||||
|
@ -90,6 +95,7 @@ function NPPronounPicker({ onChange, pronoun, asObject }: { pronoun: PronounSele
|
||||||
const prs = labels(!!asObject)[display];
|
const prs = labels(!!asObject)[display];
|
||||||
const pSpec = "near" in prs ? prs[pronoun.distance] : prs;
|
const pSpec = "near" in prs ? prs[pronoun.distance] : prs;
|
||||||
return <div style={{ maxWidth: "225px", minWidth: "125px", padding: 0 }}>
|
return <div style={{ maxWidth: "225px", minWidth: "125px", padding: 0 }}>
|
||||||
|
{clearButton}
|
||||||
<div className="d-flex flex-row justify-content-around mb-3">
|
<div className="d-flex flex-row justify-content-around mb-3">
|
||||||
<ButtonSelect
|
<ButtonSelect
|
||||||
xSmall
|
xSmall
|
||||||
|
|
Loading…
Reference in New Issue