refactor: some typescript improvements
This commit is contained in:
parent
44fbd0cd2b
commit
439a9045da
|
@ -2,7 +2,7 @@ import axios from "axios";
|
|||
|
||||
import { applyIfSecretExists } from "../utils/getSecrets";
|
||||
|
||||
async function rebuildNetlifySiteWithNewData_inner(cookie) {
|
||||
async function rebuildNetlifySiteWithNewData_inner(cookie: string) {
|
||||
let payload = {};
|
||||
let response = await axios.post(cookie, payload);
|
||||
let data = response.data;
|
||||
|
@ -10,6 +10,6 @@ async function rebuildNetlifySiteWithNewData_inner(cookie) {
|
|||
}
|
||||
|
||||
export async function rebuildNetlifySiteWithNewData() {
|
||||
let cookie = process.env.REBUIDNETLIFYHOOKURL;
|
||||
const cookie = process.env.REBUIDNETLIFYHOOKURL || "";
|
||||
await applyIfSecretExists(cookie, rebuildNetlifySiteWithNewData_inner);
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@ import { FetchedQuestion, Platform } from "./";
|
|||
const platformName = "betfair";
|
||||
|
||||
/* Definitions */
|
||||
let endpoint = process.env.SECRET_BETFAIR_ENDPOINT;
|
||||
const endpoint = process.env.SECRET_BETFAIR_ENDPOINT;
|
||||
|
||||
/* Utilities */
|
||||
let arraysEqual = (a, b) => {
|
||||
const arraysEqual = (a: string[], b: string[]) => {
|
||||
if (a === b) return true;
|
||||
if (a == null || b == null) return false;
|
||||
if (a.length !== b.length) return false;
|
||||
|
@ -26,7 +26,8 @@ let arraysEqual = (a, b) => {
|
|||
}
|
||||
return true;
|
||||
};
|
||||
let mergeRunners = (runnerCatalog, runnerBook) => {
|
||||
|
||||
const mergeRunners = (runnerCatalog, runnerBook) => {
|
||||
let keys = Object.keys(runnerCatalog);
|
||||
let result = [];
|
||||
for (let key of keys) {
|
||||
|
|
|
@ -8,8 +8,8 @@ import { Platform } from "./";
|
|||
const platformName = "givewellopenphil";
|
||||
|
||||
/* Support functions */
|
||||
async function fetchPage(url: string) {
|
||||
let response = await axios({
|
||||
async function fetchPage(url: string): Promise<string> {
|
||||
const response = await axios({
|
||||
url: url,
|
||||
method: "GET",
|
||||
headers: {
|
||||
|
|
|
@ -5,13 +5,14 @@ import { Question } from "@prisma/client";
|
|||
import { prisma } from "../database/prisma";
|
||||
import { platforms } from "../platforms";
|
||||
|
||||
let cookie = process.env.ALGOLIA_MASTER_API_KEY;
|
||||
const algoliaAppId = process.env.NEXT_PUBLIC_ALGOLIA_APP_ID;
|
||||
let cookie = process.env.ALGOLIA_MASTER_API_KEY || "";
|
||||
const algoliaAppId = process.env.NEXT_PUBLIC_ALGOLIA_APP_ID || "";
|
||||
const client = algoliasearch(algoliaAppId, cookie);
|
||||
const index = client.initIndex("metaforecast");
|
||||
|
||||
export type AlgoliaQuestion = Omit<Question, "timestamp"> & {
|
||||
timestamp: string;
|
||||
optionsstringforsearch?: string;
|
||||
};
|
||||
|
||||
const getoptionsstringforsearch = (record: Question): string => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { EventHandler, SyntheticEvent, useState } from "react";
|
||||
import React, { ChangeEvent, EventHandler, SyntheticEvent, useState } from "react";
|
||||
|
||||
import { Button } from "../common/Button";
|
||||
import { InfoBox } from "../common/InfoBox";
|
||||
|
@ -18,7 +18,7 @@ export const DashboardCreator: React.FC<Props> = ({ handleSubmit }) => {
|
|||
const [value, setValue] = useState(exampleInput);
|
||||
const [acting, setActing] = useState(false);
|
||||
|
||||
const handleChange = (event) => {
|
||||
const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setValue(event.target.value);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* Imports */
|
||||
import React from "react";
|
||||
import { Handles, Rail, Slider, Tracks } from "react-compound-slider";
|
||||
import {
|
||||
GetHandleProps, GetTrackProps, Handles, Rail, Slider, SliderItem, Tracks
|
||||
} from "react-compound-slider";
|
||||
|
||||
// https://sghall.github.io/react-compound-slider/#/getting-started/tutorial
|
||||
|
||||
|
@ -24,12 +25,11 @@ const railStyle = {
|
|||
};
|
||||
|
||||
/* Support functions */
|
||||
function Handle({
|
||||
handle: { id, value, percent },
|
||||
getHandleProps,
|
||||
displayFunction,
|
||||
handleWidth,
|
||||
}) {
|
||||
const Handle: React.FC<{
|
||||
handle: SliderItem;
|
||||
getHandleProps: GetHandleProps;
|
||||
displayFunction: (value: number) => string;
|
||||
}> = ({ handle: { id, value, percent }, getHandleProps, displayFunction }) => {
|
||||
return (
|
||||
<>
|
||||
<div className="justify-center text-center text-gray-600 text-xs">
|
||||
|
@ -53,9 +53,13 @@ function Handle({
|
|||
></div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
function Track({ source, target, getTrackProps }) {
|
||||
const Track: React.FC<{
|
||||
source: SliderItem;
|
||||
target: SliderItem;
|
||||
getTrackProps: GetTrackProps;
|
||||
}> = ({ source, target, getTrackProps }) => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
@ -74,16 +78,15 @@ function Track({ source, target, getTrackProps }) {
|
|||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
interface Props {
|
||||
value: number;
|
||||
onChange: (event: any) => void;
|
||||
onChange: (value: number) => void;
|
||||
displayFunction: (value: number) => string;
|
||||
}
|
||||
|
||||
/* Body */
|
||||
// Two functions, essentially identical.
|
||||
export const SliderElement: React.FC<Props> = ({
|
||||
onChange,
|
||||
value,
|
||||
|
@ -96,21 +99,20 @@ export const SliderElement: React.FC<Props> = ({
|
|||
}
|
||||
domain={[0, 200]}
|
||||
values={[value]}
|
||||
onChange={onChange}
|
||||
onChange={(values) => onChange(values[0])}
|
||||
>
|
||||
<Rail>
|
||||
{({ getRailProps }) => <div style={railStyle} {...getRailProps()} />}
|
||||
</Rail>
|
||||
<Handles>
|
||||
{({ handles, getHandleProps }) => (
|
||||
<div className="slider-handles">
|
||||
<div>
|
||||
{handles.map((handle) => (
|
||||
<Handle
|
||||
key={handle.id}
|
||||
handle={handle}
|
||||
getHandleProps={getHandleProps}
|
||||
displayFunction={displayFunction}
|
||||
handleWidth={"15em"}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
@ -118,7 +120,7 @@ export const SliderElement: React.FC<Props> = ({
|
|||
</Handles>
|
||||
<Tracks right={false}>
|
||||
{({ tracks, getTrackProps }) => (
|
||||
<div className="slider-tracks">
|
||||
<div>
|
||||
{tracks.map(({ id, source, target }) => (
|
||||
<Track
|
||||
key={id}
|
||||
|
|
|
@ -173,7 +173,7 @@ export const QuestionCard: React.FC<Props> = ({
|
|||
</div>
|
||||
)}
|
||||
|
||||
{question.platform.id === "guesstimate" && (
|
||||
{question.platform.id === "guesstimate" && question.visualization && (
|
||||
<img
|
||||
className="rounded-sm"
|
||||
src={question.visualization}
|
||||
|
|
|
@ -74,7 +74,7 @@ const LargeQuestionCard: React.FC<{
|
|||
</div>
|
||||
|
||||
<div className="mb-8">
|
||||
{question.platform.id === "guesstimate" ? (
|
||||
{question.platform.id === "guesstimate" && question.visualization ? (
|
||||
<a className="no-underline" href={question.url} target="_blank">
|
||||
<img
|
||||
className="rounded-sm"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { ChangeEvent } from "react";
|
||||
|
||||
interface Props {
|
||||
value: string;
|
||||
onChange: (v: string) => void;
|
||||
|
@ -9,7 +11,7 @@ export const QueryForm: React.FC<Props> = ({
|
|||
onChange,
|
||||
placeholder,
|
||||
}) => {
|
||||
const handleInputChange = (event) => {
|
||||
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
event.preventDefault();
|
||||
onChange(event.target.value); // In this case, the query, e.g. "COVID.19"
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useRouter } from "next/router";
|
||||
import React, { Fragment, useMemo, useState } from "react";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import { useQuery } from "urql";
|
||||
|
||||
import { PlatformConfig } from "../../../backend/platforms";
|
||||
|
@ -126,7 +126,8 @@ export const SearchScreen: React.FC<Props> = ({
|
|||
};
|
||||
|
||||
const updateRoute = () => {
|
||||
const stringify = (key: string, value: any) => {
|
||||
const stringify = (key: string, obj: { [k: string]: any }) => {
|
||||
const value = obj[key];
|
||||
if (key === "forecastingPlatforms") {
|
||||
return value.join("|");
|
||||
} else {
|
||||
|
@ -134,15 +135,16 @@ export const SearchScreen: React.FC<Props> = ({
|
|||
}
|
||||
};
|
||||
|
||||
const query = {};
|
||||
const query: { [k: string]: string } = {};
|
||||
for (const key of Object.keys(defaultQueryParameters)) {
|
||||
const value = stringify(key, queryParameters[key]);
|
||||
const defaultValue = stringify(key, defaultQueryParameters[key]);
|
||||
const value = stringify(key, queryParameters);
|
||||
const defaultValue = stringify(key, defaultQueryParameters);
|
||||
if (value === defaultValue) continue;
|
||||
query[key] = value;
|
||||
}
|
||||
|
||||
if (numDisplay !== defaultNumDisplay) query["numDisplay"] = numDisplay;
|
||||
if (numDisplay !== defaultNumDisplay)
|
||||
query["numDisplay"] = String(numDisplay);
|
||||
|
||||
router.replace(
|
||||
{
|
||||
|
@ -191,8 +193,8 @@ export const SearchScreen: React.FC<Props> = ({
|
|||
(Math.round(value) === 1 ? "" : "s")
|
||||
);
|
||||
};
|
||||
const onChangeSliderForNumDisplay = (event) => {
|
||||
setNumDisplay(Math.round(event[0]));
|
||||
const onChangeSliderForNumDisplay = (value: number) => {
|
||||
setNumDisplay(Math.round(value));
|
||||
setForceSearch(forceSearch + 1); // FIXME - force new search iff numDisplay is greater than last search limit
|
||||
};
|
||||
|
||||
|
@ -200,10 +202,10 @@ export const SearchScreen: React.FC<Props> = ({
|
|||
const displayFunctionNumForecasts = (value: number) => {
|
||||
return "# Forecasts > " + Math.round(value);
|
||||
};
|
||||
const onChangeSliderForNumForecasts = (event) => {
|
||||
const onChangeSliderForNumForecasts = (value: number) => {
|
||||
setQueryParameters({
|
||||
...queryParameters,
|
||||
forecastsThreshold: Math.round(event[0]),
|
||||
forecastsThreshold: Math.round(value),
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -230,7 +232,7 @@ export const SearchScreen: React.FC<Props> = ({
|
|||
|
||||
/* Final return */
|
||||
return (
|
||||
<Fragment>
|
||||
<>
|
||||
<label className="mb-4 mt-4 flex flex-row justify-center items-center">
|
||||
<div className="w-10/12 mb-2">
|
||||
<QueryForm
|
||||
|
@ -317,6 +319,6 @@ export const SearchScreen: React.FC<Props> = ({
|
|||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
</Fragment>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -36,5 +36,8 @@ export const getUrqlClientOptions = (ssr: SSRExchange) => ({
|
|||
export const ssrUrql = () => {
|
||||
const ssrCache = ssrExchange({ isClient: false });
|
||||
const client = initUrqlClient(getUrqlClientOptions(ssrCache), false);
|
||||
if (!client) {
|
||||
throw new Error("Expected non-null client instance from initUrqlClient");
|
||||
}
|
||||
return [ssrCache, client] as const;
|
||||
};
|
||||
|
|
|
@ -1,18 +1,31 @@
|
|||
import algoliasearch from "algoliasearch";
|
||||
|
||||
import { Hit } from "@algolia/client-search";
|
||||
|
||||
import { AlgoliaQuestion } from "../../backend/utils/algolia";
|
||||
|
||||
const client = algoliasearch(
|
||||
process.env.NEXT_PUBLIC_ALGOLIA_APP_ID,
|
||||
process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_KEY
|
||||
process.env.NEXT_PUBLIC_ALGOLIA_APP_ID || "",
|
||||
process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_KEY || ""
|
||||
);
|
||||
const index = client.initIndex("metaforecast");
|
||||
|
||||
let buildFilter = ({
|
||||
interface SearchOpts {
|
||||
queryString: string;
|
||||
hitsPerPage?: number;
|
||||
starsThreshold: number;
|
||||
filterByPlatforms: string[];
|
||||
forecastsThreshold: number;
|
||||
}
|
||||
|
||||
const buildFilter = ({
|
||||
starsThreshold,
|
||||
filterByPlatforms,
|
||||
forecastsThreshold,
|
||||
}) => {
|
||||
}: Pick<
|
||||
SearchOpts,
|
||||
"starsThreshold" | "filterByPlatforms" | "forecastsThreshold"
|
||||
>) => {
|
||||
const starsFilter = starsThreshold
|
||||
? `qualityindicators.stars >= ${starsThreshold}`
|
||||
: null;
|
||||
|
@ -35,26 +48,15 @@ let buildFilter = ({
|
|||
return finalFilter;
|
||||
};
|
||||
|
||||
let buildFacetFilter = ({ filterByPlatforms }) => {
|
||||
let platformsFilter = [];
|
||||
if (filterByPlatforms.length > 0) {
|
||||
platformsFilter = [
|
||||
[filterByPlatforms.map((platform) => `platform:${platform}`)],
|
||||
];
|
||||
}
|
||||
console.log(platformsFilter);
|
||||
console.log(
|
||||
"searchWithAlgolia.js/searchWithAlgolia/buildFacetFilter",
|
||||
platformsFilter
|
||||
);
|
||||
return platformsFilter;
|
||||
};
|
||||
|
||||
let noExactMatch = (queryString, result) => {
|
||||
const noExactMatch = (queryString: string, result: Hit<AlgoliaQuestion>) => {
|
||||
queryString = queryString.toLowerCase();
|
||||
let title = result.title.toLowerCase();
|
||||
let description = result.description.toLowerCase();
|
||||
let optionsstringforsearch = result.optionsstringforsearch.toLowerCase();
|
||||
|
||||
const title = result.title.toLowerCase();
|
||||
const description = result.description.toLowerCase();
|
||||
const optionsstringforsearch = (
|
||||
result.optionsstringforsearch || ""
|
||||
).toLowerCase();
|
||||
|
||||
return !(
|
||||
title.includes(queryString) ||
|
||||
description.includes(queryString) ||
|
||||
|
@ -62,14 +64,6 @@ let noExactMatch = (queryString, result) => {
|
|||
);
|
||||
};
|
||||
|
||||
interface SearchOpts {
|
||||
queryString: string;
|
||||
hitsPerPage?: number;
|
||||
starsThreshold: number;
|
||||
filterByPlatforms: string[];
|
||||
forecastsThreshold: number;
|
||||
}
|
||||
|
||||
// only query string
|
||||
export default async function searchWithAlgolia({
|
||||
queryString,
|
||||
|
|
Loading…
Reference in New Issue
Block a user