Compare commits
No commits in common. "beb9413a90a8a79a335ec27ee235db84eeb146b9" and "0b9cd7ff54e57a9d5e4992a494e69f2cc28cd458" have entirely different histories.
beb9413a90
...
0b9cd7ff54
@ -25,8 +25,6 @@ module.exports = {
|
|||||||
"unused-vars": "off",
|
"unused-vars": "off",
|
||||||
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
|
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
|
||||||
"no-redeclare": "off",
|
"no-redeclare": "off",
|
||||||
"@typescript-eslint/no-redeclare": ["error"],
|
"@typescript-eslint/no-redeclare": ["error"]
|
||||||
"quotes": ["error", "double"],
|
|
||||||
"no-warning-comments": "off"
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
"typescript": "^4.4.3"
|
"typescript": "^4.4.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jsonwebtoken": "^8.5.1",
|
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2"
|
"react-dom": "^17.0.2"
|
||||||
}
|
}
|
||||||
|
@ -37,10 +37,6 @@ input {
|
|||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchResultHeader {
|
|
||||||
padding-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.synclass {
|
.synclass {
|
||||||
color: #a63333;
|
color: #a63333;
|
||||||
i {
|
i {
|
||||||
|
104
src/App.tsx
104
src/App.tsx
@ -1,50 +1,72 @@
|
|||||||
import React, {useState} from "react";
|
import React, {useState} from 'react';
|
||||||
|
|
||||||
import "./App.scss";
|
import './App.scss';
|
||||||
import {SaiEntryProps, JutEntryProps, ElesuEntryProps, TukEntryProps, Conlang, SearchDirection} from "./dbtypes";
|
import {SaiEntryProps, JutEntryProps, ElesuEntryProps, TukEntryProps} from './dbtypes';
|
||||||
import {SaiEntry, JutEntry, ElesuEntry, TukEntry} from "./Entries";
|
import {SaiEntry, JutEntry, ElesuEntry, TukEntry} from './Entries';
|
||||||
import {setPassword, searchEntry} from "./requests";
|
|
||||||
|
|
||||||
const PasswordDialog = (_props) => {
|
const backendUrl = 'https://kucinakobackend.ichigo.everydayimshuflin.com';
|
||||||
const [password, setPasswordStr] = useState("");
|
|
||||||
|
|
||||||
const modal = (): any => document.querySelector(".passwordDialog");
|
enum Conlang {
|
||||||
const save = () => {
|
Saimiar = 'saimiar',
|
||||||
setPassword(password);
|
Elesu = 'elesu',
|
||||||
modal().close();
|
Tukvaysi = 'tukvaysi',
|
||||||
location.reload(); // TODO this is a hack
|
Juteyuji = 'juteyuji',
|
||||||
};
|
}
|
||||||
|
|
||||||
const cancel = () => {
|
enum SearchDirection {
|
||||||
modal().close();
|
ToConlang,
|
||||||
};
|
ToEnglish
|
||||||
|
}
|
||||||
return (
|
|
||||||
<dialog className="passwordDialog">
|
|
||||||
<input type="password" placeholder="enter password" value={password} onChange={ (evt) => setPasswordStr(evt.target.value) } />
|
|
||||||
<button onClick={save}>Save</button>
|
|
||||||
<button onClick={cancel}>Cancel</button>
|
|
||||||
</dialog>);
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderConlang = (conlang: Conlang): string => {
|
const renderConlang = (conlang: Conlang): string => {
|
||||||
if (conlang === Conlang.Saimiar) {
|
if (conlang === Conlang.Saimiar) {
|
||||||
return "Saimiar";
|
return 'Saimiar';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conlang === Conlang.Elesu) {
|
if (conlang === Conlang.Elesu) {
|
||||||
return "Elésu";
|
return 'Elésu';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conlang === Conlang.Juteyuji) {
|
if (conlang === Conlang.Juteyuji) {
|
||||||
return "Juteyuji";
|
return 'Juteyuji';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conlang === Conlang.Tukvaysi) {
|
if (conlang === Conlang.Tukvaysi) {
|
||||||
return "Tukvaysi";
|
return 'Tukvaysi';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function buildRequest(searchTerm: string, conlang: Conlang, direction: SearchDirection, jsonHandler: (json: Object) => void) {
|
||||||
|
const specForConlang = {
|
||||||
|
[Conlang.Saimiar]: 'sai',
|
||||||
|
[Conlang.Juteyuji]: 'jut',
|
||||||
|
[Conlang.Tukvaysi]: 'tuk',
|
||||||
|
[Conlang.Elesu]: 'elesu',
|
||||||
|
};
|
||||||
|
|
||||||
|
const offset = 0;
|
||||||
|
const limit = 20;
|
||||||
|
|
||||||
|
const conlangDb = conlang.toString();
|
||||||
|
const conlangSpec = specForConlang[conlang];
|
||||||
|
const field = direction === SearchDirection.ToConlang ? 'eng' : conlangSpec;
|
||||||
|
|
||||||
|
const params = new URLSearchParams([
|
||||||
|
[field, `like.*${searchTerm}*`],
|
||||||
|
['order', conlangSpec],
|
||||||
|
['limit', limit],
|
||||||
|
['offset', offset],
|
||||||
|
]);
|
||||||
|
|
||||||
|
const effectiveUri = `${backendUrl}/${conlangDb}?${params}`;
|
||||||
|
|
||||||
|
fetch(`${effectiveUri}`)
|
||||||
|
.then((resp) => resp.json())
|
||||||
|
.then((json) => {
|
||||||
|
jsonHandler(json);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
interface EntryProps {
|
interface EntryProps {
|
||||||
conlang: Conlang;
|
conlang: Conlang;
|
||||||
entry: SaiEntryProps | JutEntryProps | ElesuEntryProps | TukEntryProps;
|
entry: SaiEntryProps | JutEntryProps | ElesuEntryProps | TukEntryProps;
|
||||||
@ -84,10 +106,9 @@ const Results = (props: ResultsProps) => {
|
|||||||
|
|
||||||
const renderedName = renderConlang(conlang);
|
const renderedName = renderConlang(conlang);
|
||||||
const searchType = (props.direction === SearchDirection.ToConlang) ? `English -> ${renderedName}` : `${renderedName} -> English`;
|
const searchType = (props.direction === SearchDirection.ToConlang) ? `English -> ${renderedName}` : `${renderedName} -> English`;
|
||||||
const result = num === 1 ? "result" : "results";
|
|
||||||
const header = (
|
const header = (
|
||||||
<div className="searchResultHeader" key="header">
|
<div className="searchResultHeader" key="header">
|
||||||
Searched for <b>{ props.searchTerm }</b>, { searchType }, found { num } { result }
|
Searched for <b>{ props.searchTerm }</b>, { searchType }, found { num } result(s)
|
||||||
</div>);
|
</div>);
|
||||||
const entries = props.searchResults.map(
|
const entries = props.searchResults.map(
|
||||||
(entry, _idx) => <Entry entry={ entry } key= { entry.id } conlang={ conlang } />,
|
(entry, _idx) => <Entry entry={ entry } key= { entry.id } conlang={ conlang } />,
|
||||||
@ -98,35 +119,35 @@ const Results = (props: ResultsProps) => {
|
|||||||
const results = props.searchResults;
|
const results = props.searchResults;
|
||||||
return (
|
return (
|
||||||
<div className="results">
|
<div className="results">
|
||||||
{ results ? content() : "No search" }
|
{ results ? content() : 'No search' }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const App = (_props) => {
|
const App = (_props) => {
|
||||||
const defaultConlang = window.sessionStorage.getItem("conlang") as Conlang || Conlang.Saimiar;
|
const defaultConlang = window.sessionStorage.getItem('conlang') as Conlang || Conlang.Saimiar;
|
||||||
const [searchResults, setSearchResults] = useState(null);
|
const [searchResults, setSearchResults] = useState(null);
|
||||||
const [conlang, setConlangState] = useState(defaultConlang);
|
const [conlang, setConlangState] = useState(defaultConlang);
|
||||||
const [direction, setDirection] = useState(null);
|
const [direction, setDirection] = useState(null);
|
||||||
const [searchTerm, setSearchTerm] = useState(null);
|
const [searchTerm, setSearchTerm] = useState(null);
|
||||||
|
|
||||||
const [searchBoxInput, setSearchBoxInput] = useState("");
|
const [searchBoxInput, setSearchBoxInput] = useState('');
|
||||||
|
|
||||||
const setConlang = (conlang: Conlang) => {
|
const setConlang = (conlang: Conlang) => {
|
||||||
setConlangState(conlang);
|
setConlangState(conlang);
|
||||||
window.sessionStorage.setItem("conlang", conlang);
|
window.sessionStorage.setItem('conlang', conlang);
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchConlang = (_evt) => {
|
const searchConlang = (_evt) => {
|
||||||
const searchTerm = searchBoxInput;
|
const searchTerm = searchBoxInput;
|
||||||
if (searchTerm === "") {
|
if (searchTerm === '') {
|
||||||
setSearchResults(null);
|
setSearchResults(null);
|
||||||
setSearchTerm(null);
|
setSearchTerm(null);
|
||||||
setDirection(null);
|
setDirection(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
searchEntry(searchTerm, conlang, SearchDirection.ToEnglish, (json) => {
|
buildRequest(searchTerm, conlang, SearchDirection.ToEnglish, (json) => {
|
||||||
setSearchResults(json);
|
setSearchResults(json);
|
||||||
setSearchTerm(searchTerm);
|
setSearchTerm(searchTerm);
|
||||||
setDirection(SearchDirection.ToEnglish);
|
setDirection(SearchDirection.ToEnglish);
|
||||||
@ -135,12 +156,12 @@ const App = (_props) => {
|
|||||||
|
|
||||||
const searchEng = (_evt) => {
|
const searchEng = (_evt) => {
|
||||||
const searchTerm = searchBoxInput;
|
const searchTerm = searchBoxInput;
|
||||||
if (searchTerm === "") {
|
if (searchTerm === '') {
|
||||||
setSearchResults(null);
|
setSearchResults(null);
|
||||||
setSearchTerm(null);
|
setSearchTerm(null);
|
||||||
setDirection(null);
|
setDirection(null);
|
||||||
} else {
|
} else {
|
||||||
searchEntry(searchTerm, conlang, SearchDirection.ToConlang, (json) => {
|
buildRequest(searchTerm, conlang, SearchDirection.ToConlang, (json) => {
|
||||||
setSearchResults(json);
|
setSearchResults(json);
|
||||||
setSearchTerm(searchTerm);
|
setSearchTerm(searchTerm);
|
||||||
setDirection(SearchDirection.ToConlang);
|
setDirection(SearchDirection.ToConlang);
|
||||||
@ -161,14 +182,8 @@ const App = (_props) => {
|
|||||||
</select>
|
</select>
|
||||||
);
|
);
|
||||||
|
|
||||||
const showPasswordBox = () => {
|
|
||||||
const modal: any = document.querySelector(".passwordDialog");
|
|
||||||
modal.showModal();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
<PasswordDialog />
|
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="search">
|
<div className="search">
|
||||||
<h1>Kucinako - Wordbook of Arzhanai languages</h1>
|
<h1>Kucinako - Wordbook of Arzhanai languages</h1>
|
||||||
@ -183,7 +198,6 @@ const App = (_props) => {
|
|||||||
{ langSelectDropdown }
|
{ langSelectDropdown }
|
||||||
<button onClick={ searchConlang } className="searchButton">{renderConlang(conlang)}</button>
|
<button onClick={ searchConlang } className="searchButton">{renderConlang(conlang)}</button>
|
||||||
<button onClick={ searchEng } className="searchButton">English</button>
|
<button onClick={ searchEng } className="searchButton">English</button>
|
||||||
<button onClick={ showPasswordBox } className="searchButton">Password</button>
|
|
||||||
</div>
|
</div>
|
||||||
<Results
|
<Results
|
||||||
searchResults={ searchResults }
|
searchResults={ searchResults }
|
||||||
|
121
src/Entries.tsx
121
src/Entries.tsx
@ -1,86 +1,15 @@
|
|||||||
import React, {useState} from "react";
|
import React from 'react';
|
||||||
|
import {declineSaimiar} from './saimiar_morphology';
|
||||||
import {Conlang} from "./dbtypes";
|
import {SaiEntryProps, JutEntryProps, ElesuEntryProps, TukEntryProps} from './dbtypes';
|
||||||
import {updateEntry, getPassword} from "./requests";
|
|
||||||
import {declineSaimiar} from "./saimiar_morphology";
|
|
||||||
import {SaiEntryProps, JutEntryProps, ElesuEntryProps, TukEntryProps} from "./dbtypes";
|
|
||||||
|
|
||||||
interface BaseProps {
|
|
||||||
id: number;
|
|
||||||
conlang: Conlang;
|
|
||||||
conlangEntry: string;
|
|
||||||
english: string;
|
|
||||||
langSpecific: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
const EntryBase = (props: BaseProps) => {
|
|
||||||
const [editing, setEditing] = useState(false);
|
|
||||||
const [english, setEnglish] = useState(props.english);
|
|
||||||
|
|
||||||
const mainEntryStyle = {
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
flexDirection: "row",
|
|
||||||
};
|
|
||||||
|
|
||||||
const controlStyle = {
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
flexDirection: "row",
|
|
||||||
minWidth: "20%",
|
|
||||||
};
|
|
||||||
|
|
||||||
const save = () => {
|
|
||||||
updateEntry(props.conlang, props.id, english);
|
|
||||||
};
|
|
||||||
|
|
||||||
const engTranslation = editing ? <input type="text" value={ english } onChange={ (evt) => setEnglish(evt.target.value) }/>
|
|
||||||
: english;
|
|
||||||
|
|
||||||
const EditControls = ({onSave}: { onSave: () => void }) => {
|
|
||||||
const cancel = () => setEditing(false);
|
|
||||||
const edit = (evt) => {
|
|
||||||
evt.preventDefault();
|
|
||||||
setEditing(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!getPassword()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (editing ? (<span>
|
|
||||||
<button onClick={ onSave }>Save</button>
|
|
||||||
<button onClick={ cancel }>Cancel</button>
|
|
||||||
</span>)
|
|
||||||
: <a href="" onClick={edit}>Edit</a>);
|
|
||||||
};
|
|
||||||
|
|
||||||
const expand = (evt) => {
|
|
||||||
evt.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="searchResult" key={ props.id }>
|
|
||||||
<div style={mainEntryStyle}>
|
|
||||||
<span><b>{ props.conlangEntry }</b> { engTranslation }</span>
|
|
||||||
<span style={controlStyle}>
|
|
||||||
<a href="" onClick={expand}>Expand</a>
|
|
||||||
<EditControls onSave={save} />
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{ props.langSpecific }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const SaiEntry = (props: {entry: SaiEntryProps}) => {
|
const SaiEntry = (props: {entry: SaiEntryProps}) => {
|
||||||
const {entry} = props;
|
const {entry} = props;
|
||||||
|
|
||||||
const synCategory = entry.syn_category;
|
const synCategory = entry.syn_category;
|
||||||
const isNominal = synCategory === "nominal";
|
const isNominal = synCategory === 'nominal';
|
||||||
|
return (
|
||||||
const langSpecific = (
|
<div className="searchResult" key={ entry.id }>
|
||||||
<div>
|
<b>{ entry.sai }</b> - { entry.eng }
|
||||||
|
<br />
|
||||||
<span className="synclass">
|
<span className="synclass">
|
||||||
<i>{ entry.syn_category }</i>
|
<i>{ entry.syn_category }</i>
|
||||||
{ entry.morph_type ? `\t\t${entry.morph_type}` : null }
|
{ entry.morph_type ? `\t\t${entry.morph_type}` : null }
|
||||||
@ -89,17 +18,15 @@ const SaiEntry = (props: {entry: SaiEntryProps}) => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
return <EntryBase id={entry.id} conlang={Conlang.Saimiar} conlangEntry={entry.sai} english={entry.eng} langSpecific={langSpecific} />;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function formatMorphology(entry) {
|
function formatMorphology(entry) {
|
||||||
const decl = declineSaimiar(entry);
|
const decl = declineSaimiar(entry);
|
||||||
if (!decl) {
|
if (!decl) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return (<span style={ {fontSize: "medium", color: "#6a3131"} } >
|
return (<span style={ {fontSize: 'medium', color: '#6a3131'} } >
|
||||||
Abs: <i>{decl.abs}</i>, Erg: <i>{decl.erg}</i>,
|
Abs: <i>{decl.abs}</i>, Erg: <i>{decl.erg}</i>,
|
||||||
Adp: <i>{decl.adp}</i>,
|
Adp: <i>{decl.adp}</i>,
|
||||||
All: <i>{decl.all}</i>,
|
All: <i>{decl.all}</i>,
|
||||||
@ -113,36 +40,40 @@ function formatMorphology(entry) {
|
|||||||
const JutEntry = (props: {entry: JutEntryProps}) => {
|
const JutEntry = (props: {entry: JutEntryProps}) => {
|
||||||
const {entry} = props;
|
const {entry} = props;
|
||||||
|
|
||||||
const langSpecific = (<div>
|
return (
|
||||||
|
<div className="searchResult" key={ entry.id }>
|
||||||
|
<b>{ entry.jut }</b> - { entry.eng }
|
||||||
|
<br/>
|
||||||
<span className="synclass">
|
<span className="synclass">
|
||||||
{entry.syn_category} { entry.syn_category === "noun" ? `- ${entry.gender}` : null }
|
{ entry.syn_category === 'noun' ? entry.gender : null }
|
||||||
</span>
|
</span>
|
||||||
</div>);
|
</div>);
|
||||||
|
|
||||||
return <EntryBase id={entry.id} conlang={Conlang.Juteyuji} conlangEntry={entry.jut} english={entry.eng} langSpecific={langSpecific} />;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const ElesuEntry = (props: {entry: ElesuEntryProps}) => {
|
const ElesuEntry = (props: {entry: ElesuEntryProps}) => {
|
||||||
const {entry} = props;
|
const {entry} = props;
|
||||||
|
|
||||||
const langSpecific = <div>
|
return (
|
||||||
|
<div className="searchResult" key={ entry.id }>
|
||||||
|
<b>{ entry.elesu }</b> - { entry.eng }
|
||||||
|
<br/>
|
||||||
<span className="synclass">
|
<span className="synclass">
|
||||||
{ entry.syn_category }
|
{ entry.syn_category }
|
||||||
</span>
|
</span>
|
||||||
</div>;
|
</div>);
|
||||||
|
|
||||||
return <EntryBase id={entry.id} conlang={Conlang.Elesu} conlangEntry={entry.elesu} english={entry.eng} langSpecific={langSpecific} />;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const TukEntry = (props: {entry: TukEntryProps}) => {
|
const TukEntry = (props: {entry: TukEntryProps}) => {
|
||||||
const {entry} = props;
|
const {entry} = props;
|
||||||
const langSpecific = <div>
|
|
||||||
|
return (
|
||||||
|
<div className="searchResult" key={ entry.id }>
|
||||||
|
<b>{ entry.tuk }</b> - { entry.eng }
|
||||||
|
<br/>
|
||||||
<span className="synclass">
|
<span className="synclass">
|
||||||
{ entry.syn_category }
|
{ entry.syn_category }
|
||||||
</span>
|
</span>
|
||||||
</div>;
|
</div>);
|
||||||
|
|
||||||
return <EntryBase id={entry.id} conlang={Conlang.Tukvaysi} conlangEntry={entry.tuk} english={entry.eng} langSpecific={langSpecific} />;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export {SaiEntry, ElesuEntry, JutEntry, TukEntry};
|
export {SaiEntry, ElesuEntry, JutEntry, TukEntry};
|
||||||
|
@ -1,15 +1,3 @@
|
|||||||
enum Conlang {
|
|
||||||
Saimiar = "saimiar",
|
|
||||||
Elesu = "elesu",
|
|
||||||
Tukvaysi = "tukvaysi",
|
|
||||||
Juteyuji = "juteyuji",
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SearchDirection {
|
|
||||||
ToConlang,
|
|
||||||
ToEnglish
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SaiEntryProps {
|
interface SaiEntryProps {
|
||||||
id: number;
|
id: number;
|
||||||
sai: string;
|
sai: string;
|
||||||
@ -47,4 +35,4 @@ interface TukEntryProps {
|
|||||||
notes: string;
|
notes: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export {SaiEntryProps, JutEntryProps, ElesuEntryProps, TukEntryProps, Conlang, SearchDirection};
|
export {SaiEntryProps, JutEntryProps, ElesuEntryProps, TukEntryProps};
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
import jwt from "jsonwebtoken";
|
|
||||||
|
|
||||||
import {Conlang, SearchDirection} from "./dbtypes";
|
|
||||||
|
|
||||||
const backendUrl = "https://kucinakobackend.ichigo.everydayimshuflin.com";
|
|
||||||
|
|
||||||
const getPassword = (): string | null => window.sessionStorage.getItem("password");
|
|
||||||
|
|
||||||
const setPassword = (password: string) => {
|
|
||||||
window.sessionStorage.setItem("password", password);
|
|
||||||
};
|
|
||||||
|
|
||||||
const makeAuthorizationHeader = (key: string): string => {
|
|
||||||
const unixTime = Date.now() / 1000;
|
|
||||||
const token = jwt.sign({role: "conlang_postgrest_rw", exp: unixTime + 60}, key);
|
|
||||||
return `Bearer ${token}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateEntry = (conlang: Conlang, id: number, english: string) => {
|
|
||||||
const url = `${backendUrl}/${conlang.toString()}?id=eq.${id}`;
|
|
||||||
|
|
||||||
const request = new Request(url, {
|
|
||||||
method: "PATCH",
|
|
||||||
headers: {
|
|
||||||
Authorization: makeAuthorizationHeader(getPassword()),
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
eng: english,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
fetch(request).then((resp) => console.log(resp));
|
|
||||||
};
|
|
||||||
|
|
||||||
function searchEntry(searchTerm: string, conlang: Conlang, direction: SearchDirection, jsonHandler: (json: Object) => void) {
|
|
||||||
const specForConlang = {
|
|
||||||
[Conlang.Saimiar]: "sai",
|
|
||||||
[Conlang.Juteyuji]: "jut",
|
|
||||||
[Conlang.Tukvaysi]: "tuk",
|
|
||||||
[Conlang.Elesu]: "elesu",
|
|
||||||
};
|
|
||||||
|
|
||||||
const offset = 0;
|
|
||||||
const limit = 20;
|
|
||||||
|
|
||||||
const conlangDb = conlang.toString();
|
|
||||||
const conlangSpec = specForConlang[conlang];
|
|
||||||
const field = direction === SearchDirection.ToConlang ? "eng" : conlangSpec;
|
|
||||||
|
|
||||||
const params = new URLSearchParams([
|
|
||||||
[field, `like.*${searchTerm}*`],
|
|
||||||
["order", conlangSpec],
|
|
||||||
["limit", limit],
|
|
||||||
["offset", offset],
|
|
||||||
] as string[][]);
|
|
||||||
|
|
||||||
const effectiveUri = `${backendUrl}/${conlangDb}?${params}`;
|
|
||||||
|
|
||||||
fetch(`${effectiveUri}`)
|
|
||||||
.then((resp) => resp.json())
|
|
||||||
.then((json) => {
|
|
||||||
jsonHandler(json);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export {backendUrl, updateEntry, getPassword, setPassword, searchEntry};
|
|
@ -12,23 +12,23 @@ type SaimiarDeclension = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function declineSaimiar(entry): SaimiarDeclension {
|
function declineSaimiar(entry): SaimiarDeclension {
|
||||||
const split = entry.sai.split(" ");
|
const split = entry.sai.split(' ');
|
||||||
const sai = split.at(-1);
|
const sai = split.at(-1);
|
||||||
const morph = entry.morph_type;
|
const morph = entry.morph_type;
|
||||||
|
|
||||||
if (morph === "-V") {
|
if (morph === '-V') {
|
||||||
return vowelDeclension(sai);
|
return vowelDeclension(sai);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (morph === "-a/i") {
|
if (morph === '-a/i') {
|
||||||
return aiDeclension(sai);
|
return aiDeclension(sai);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (morph === "e-") {
|
if (morph === 'e-') {
|
||||||
return initalDeclension(sai);
|
return initalDeclension(sai);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (morph === "-C") {
|
if (morph === '-C') {
|
||||||
return consonantDeclension(sai);
|
return consonantDeclension(sai);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ function declineSaimiar(entry): SaimiarDeclension {
|
|||||||
|
|
||||||
function vowelDeclension(sai: string): SaimiarDeclension {
|
function vowelDeclension(sai: string): SaimiarDeclension {
|
||||||
const {root, ending} = rootEndingPair(sai);
|
const {root, ending} = rootEndingPair(sai);
|
||||||
const adpEnding = ending === "u" ? "ys" : `${ending}s`;
|
const adpEnding = ending === 'u' ? 'ys' : `${ending}s`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
abs: `${root}${ending}`,
|
abs: `${root}${ending}`,
|
||||||
@ -69,8 +69,8 @@ function aiDeclension(sai: string): SaimiarDeclension {
|
|||||||
|
|
||||||
function consonantDeclension(sai: string): SaimiarDeclension {
|
function consonantDeclension(sai: string): SaimiarDeclension {
|
||||||
const split = rootEndingPair(sai);
|
const split = rootEndingPair(sai);
|
||||||
const root = split.ending === "ø" ? split.root : sai;
|
const root = split.ending === 'ø' ? split.root : sai;
|
||||||
const absFinal = split.ending === "ø" ? "ø" : "";
|
const absFinal = split.ending === 'ø' ? 'ø' : '';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
abs: `${root}${absFinal}`,
|
abs: `${root}${absFinal}`,
|
||||||
@ -84,7 +84,7 @@ function consonantDeclension(sai: string): SaimiarDeclension {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const vowels = ["a", "e", "ê", "i", "o", "ô", "u", "y"];
|
const vowels = ['a', 'e', 'ê', 'i', 'o', 'ô', 'u', 'y'];
|
||||||
|
|
||||||
function initalDeclension(sai: string): SaimiarDeclension {
|
function initalDeclension(sai: string): SaimiarDeclension {
|
||||||
const initial = sai.slice(0, 1);
|
const initial = sai.slice(0, 1);
|
||||||
@ -92,8 +92,8 @@ function initalDeclension(sai: string): SaimiarDeclension {
|
|||||||
|
|
||||||
const finalRootSound = root.slice(-1);
|
const finalRootSound = root.slice(-1);
|
||||||
const finalVowel = vowels.includes(finalRootSound);
|
const finalVowel = vowels.includes(finalRootSound);
|
||||||
const instEnding = finalVowel ? "ŕø" : "ar";
|
const instEnding = finalVowel ? 'ŕø' : 'ar';
|
||||||
const relEnding = finalVowel ? "źi" : "ai";
|
const relEnding = finalVowel ? 'źi' : 'ai';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
abs: `${initial}${root}`,
|
abs: `${initial}${root}`,
|
||||||
|
87
yarn.lock
87
yarn.lock
@ -1432,11 +1432,6 @@ browserslist@^4.0.0, browserslist@^4.16.0, browserslist@^4.16.6, browserslist@^4
|
|||||||
escalade "^3.1.1"
|
escalade "^3.1.1"
|
||||||
node-releases "^1.1.75"
|
node-releases "^1.1.75"
|
||||||
|
|
||||||
buffer-equal-constant-time@1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
|
||||||
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
|
|
||||||
|
|
||||||
buffer-from@^1.0.0:
|
buffer-from@^1.0.0:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
|
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
|
||||||
@ -2178,13 +2173,6 @@ ecc-jsbn@~0.1.1:
|
|||||||
jsbn "~0.1.0"
|
jsbn "~0.1.0"
|
||||||
safer-buffer "^2.1.0"
|
safer-buffer "^2.1.0"
|
||||||
|
|
||||||
ecdsa-sig-formatter@1.0.11:
|
|
||||||
version "1.0.11"
|
|
||||||
resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
|
|
||||||
integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
|
|
||||||
dependencies:
|
|
||||||
safe-buffer "^5.0.1"
|
|
||||||
|
|
||||||
ee-first@1.1.1:
|
ee-first@1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
|
resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
|
||||||
@ -3585,22 +3573,6 @@ json5@^2.1.0, json5@^2.1.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
minimist "^1.2.5"
|
minimist "^1.2.5"
|
||||||
|
|
||||||
jsonwebtoken@^8.5.1:
|
|
||||||
version "8.5.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
|
|
||||||
integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
|
|
||||||
dependencies:
|
|
||||||
jws "^3.2.2"
|
|
||||||
lodash.includes "^4.3.0"
|
|
||||||
lodash.isboolean "^3.0.3"
|
|
||||||
lodash.isinteger "^4.0.4"
|
|
||||||
lodash.isnumber "^3.0.3"
|
|
||||||
lodash.isplainobject "^4.0.6"
|
|
||||||
lodash.isstring "^4.0.1"
|
|
||||||
lodash.once "^4.0.0"
|
|
||||||
ms "^2.1.1"
|
|
||||||
semver "^5.6.0"
|
|
||||||
|
|
||||||
jsprim@^1.2.2:
|
jsprim@^1.2.2:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz"
|
resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz"
|
||||||
@ -3619,23 +3591,6 @@ jsprim@^1.2.2:
|
|||||||
array-includes "^3.1.2"
|
array-includes "^3.1.2"
|
||||||
object.assign "^4.1.2"
|
object.assign "^4.1.2"
|
||||||
|
|
||||||
jwa@^1.4.1:
|
|
||||||
version "1.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
|
|
||||||
integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
|
|
||||||
dependencies:
|
|
||||||
buffer-equal-constant-time "1.0.1"
|
|
||||||
ecdsa-sig-formatter "1.0.11"
|
|
||||||
safe-buffer "^5.0.1"
|
|
||||||
|
|
||||||
jws@^3.2.2:
|
|
||||||
version "3.2.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
|
|
||||||
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
|
|
||||||
dependencies:
|
|
||||||
jwa "^1.4.1"
|
|
||||||
safe-buffer "^5.0.1"
|
|
||||||
|
|
||||||
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
|
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
|
||||||
version "3.2.2"
|
version "3.2.2"
|
||||||
resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz"
|
resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz"
|
||||||
@ -3723,36 +3678,6 @@ lodash.clonedeep@^4.5.0:
|
|||||||
resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz"
|
resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz"
|
||||||
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
|
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
|
||||||
|
|
||||||
lodash.includes@^4.3.0:
|
|
||||||
version "4.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
|
|
||||||
integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
|
|
||||||
|
|
||||||
lodash.isboolean@^3.0.3:
|
|
||||||
version "3.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
|
|
||||||
integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
|
|
||||||
|
|
||||||
lodash.isinteger@^4.0.4:
|
|
||||||
version "4.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
|
|
||||||
integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
|
|
||||||
|
|
||||||
lodash.isnumber@^3.0.3:
|
|
||||||
version "3.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
|
|
||||||
integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
|
|
||||||
|
|
||||||
lodash.isplainobject@^4.0.6:
|
|
||||||
version "4.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
|
|
||||||
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
|
|
||||||
|
|
||||||
lodash.isstring@^4.0.1:
|
|
||||||
version "4.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
|
|
||||||
integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
|
|
||||||
|
|
||||||
lodash.memoize@^4.1.2:
|
lodash.memoize@^4.1.2:
|
||||||
version "4.1.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz"
|
resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz"
|
||||||
@ -3763,11 +3688,6 @@ lodash.merge@^4.6.2:
|
|||||||
resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
|
resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
|
||||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||||
|
|
||||||
lodash.once@^4.0.0:
|
|
||||||
version "4.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
|
||||||
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
|
|
||||||
|
|
||||||
lodash.sortby@^4.7.0:
|
lodash.sortby@^4.7.0:
|
||||||
version "4.7.0"
|
version "4.7.0"
|
||||||
resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz"
|
resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz"
|
||||||
@ -3975,11 +3895,6 @@ ms@2.1.2:
|
|||||||
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
|
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
|
||||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||||
|
|
||||||
ms@^2.1.1:
|
|
||||||
version "2.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
|
||||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
|
||||||
|
|
||||||
msgpackr-extract@^1.0.13:
|
msgpackr-extract@^1.0.13:
|
||||||
version "1.0.13"
|
version "1.0.13"
|
||||||
resolved "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-1.0.13.tgz"
|
resolved "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-1.0.13.tgz"
|
||||||
@ -5207,7 +5122,7 @@ scheduler@^0.20.2:
|
|||||||
loose-envify "^1.1.0"
|
loose-envify "^1.1.0"
|
||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
|
|
||||||
semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.0:
|
semver@^5.4.1, semver@^5.5.0, semver@^5.7.0:
|
||||||
version "5.7.1"
|
version "5.7.1"
|
||||||
resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
|
resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
|
||||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||||
|
Loading…
Reference in New Issue
Block a user