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