diff --git a/common/links.tsx b/common/links.tsx index 930f26f5..ef537d30 100644 --- a/common/links.tsx +++ b/common/links.tsx @@ -1,11 +1,13 @@ -import React, { ReactElement, PropsWithChildren, ReactNode } from 'react'; -import { default as NextLink, LinkProps } from 'next/link'; -import { getCategoryString } from './categories'; -import { isAbsoluteUrl, stripLocaleAndPlan, stripSlashes } from '@/utils/urls'; +import React, { PropsWithChildren, ReactElement, ReactNode } from 'react'; +import NextLink, { LinkProps } from 'next/link'; + +import { useLocale } from 'next-intl'; + +import { ACTIONS_PATH, INDICATORS_PATH } from '@/constants/routes.mjs'; import { usePlan } from '@/context/plan'; +import { isAbsoluteUrl, stripLocaleAndPlan, stripSlashes } from '@/utils/urls'; import { PlanContextFragment } from './__generated__/graphql'; -import { ACTIONS_PATH, INDICATORS_PATH } from '@/constants/routes'; -import { useLocale } from 'next-intl'; +import { getCategoryString } from './categories'; export function usePrependPlanAndLocale(path: string) { const plan = usePlan(); @@ -83,7 +85,7 @@ export const replaceHashWithoutScrolling = (hash) => export function IndicatorLink({ id, ...other -}: { id: string | number; children: ReactNode } & LinkProps) { +}: { id: string | number; children: ReactNode } & Omit) { const href = usePrependPlanAndLocale(getIndicatorLinkProps(id).href); return ; diff --git a/common/search.ts b/common/search.ts index 320e616d..bb034ad4 100644 --- a/common/search.ts +++ b/common/search.ts @@ -1,8 +1,9 @@ -import { ApolloClient, InMemoryCache, gql } from '@apollo/client'; -import { PlanContextFragment } from './__generated__/graphql'; +import { ApolloClient, gql, InMemoryCache } from '@apollo/client'; + import { trackSearch } from '@/components/MatomoAnalytics'; +import { PlanContextFragment } from './__generated__/graphql'; -const SEARCH_QUERY = gql` +export const SEARCH_QUERY = gql` query SearchQuery( $plan: ID! $query: String! diff --git a/common/utils.ts b/common/utils.ts index 6112ba8e..69ab290c 100644 --- a/common/utils.ts +++ b/common/utils.ts @@ -1,6 +1,6 @@ /* Common utility functions */ -export function slugify(text) { +export function slugify(text: string) { return text .toString() .toLowerCase() @@ -11,14 +11,14 @@ export function slugify(text) { .replace(/-+$/, ''); // Trim - from end of text } -export function capitalizeFirstLetter(s) { +export function capitalizeFirstLetter(s: string) { return s.charAt(0).toUpperCase() + s.slice(1); } const MAX_WORDS_PER_LINE = 2; const MIN_CHARACTERS_PER_WORD = 4; -export function splitLines(text, lineSeparator = '
') { +export function splitLines(text: string | null, lineSeparator = '
') { if (text == null || typeof text != 'string') { return text; } @@ -26,8 +26,8 @@ export function splitLines(text, lineSeparator = '
') { if (words.length === 1) { return text; } - const lines = []; - let line = []; + const lines: string[][] = []; + let line: string[] = []; for (const word of words) { line.push(word); if ( diff --git a/components/common/SearchView.js b/components/common/SearchView.js index 148ca464..50c80680 100644 --- a/components/common/SearchView.js +++ b/components/common/SearchView.js @@ -1,89 +1,29 @@ import { useEffect, useState } from 'react'; -import PropTypes from 'prop-types'; -import { gql } from '@apollo/client'; -import { useQuery } from '@apollo/experimental-nextjs-app-support/ssr'; -import styled from 'styled-components'; + +import { useQuery } from '@apollo/client'; +import { getActionTermContext } from 'common/i18n'; +import { Link } from 'common/links'; +import Button from 'components/common/Button'; +import TextInput from 'components/common/TextInput'; +import PlanChip from 'components/plans/PlanChip'; +import { usePlan } from 'context/plan'; +import { useTranslations } from 'next-intl'; import { readableColor } from 'polished'; +import PropTypes from 'prop-types'; import { - Container, - Row, + Alert, Col, + Container, + FormGroup, Input, Label, - FormGroup, - Alert, + Row, } from 'reactstrap'; -import { Link } from 'common/links'; -import { getActionTermContext } from 'common/i18n'; -import TextInput from 'components/common/TextInput'; -import Button from 'components/common/Button'; -import PlanChip from 'components/plans/PlanChip'; -import { usePlan } from 'context/plan'; -import ContentLoader from './ContentLoader'; -import { useTranslations } from 'next-intl'; -import { trackSearch } from '../MatomoAnalytics'; +import styled from 'styled-components'; -const SEARCH_QUERY = gql` - query SearchQuery( - $plan: ID! - $query: String! - $onlyOtherPlans: Boolean - $clientUrl: String - ) { - search( - plan: $plan - query: $query - includeRelatedPlans: true - onlyOtherPlans: $onlyOtherPlans - ) { - hits { - title - url(clientUrl: $clientUrl) - highlight - plan { - identifier - image { - rendition(size: "128x128", crop: true) { - src - } - } - name - shortName - organization { - name - } - } - object { - __typename - ... on Action { - identifier - primaryOrg { - name - logo { - rendition(size: "128x128", crop: true) { - src - } - } - } - } - ... on Indicator { - id - } - } - page { - title - ... on CategoryPage { - category { - level { - name - } - } - } - } - } - } - } -`; +import { SEARCH_QUERY } from '@/common/search'; +import { trackSearch } from '../MatomoAnalytics'; +import ContentLoader from './ContentLoader'; const SearchSection = styled.div` padding-bottom: ${(props) => props.theme.spaces.s050}; diff --git a/components/indicators/IndicatorProgressBar.tsx b/components/indicators/IndicatorProgressBar.tsx index 9a42475c..f606c900 100644 --- a/components/indicators/IndicatorProgressBar.tsx +++ b/components/indicators/IndicatorProgressBar.tsx @@ -5,7 +5,7 @@ import dayjs from 'common/dayjs'; import { useWindowSize } from 'common/hooks/use-window-size'; import { IndicatorLink } from 'common/links'; import Switch from 'components/common/Switch'; -import { animate, motion, useAnimate, useInView } from 'framer-motion'; +import { animate, motion, Segment, useAnimate, useInView } from 'framer-motion'; import { useLocale, useTranslations } from 'next-intl'; import { readableColor } from 'polished'; import styled, { useTheme } from 'styled-components'; @@ -229,10 +229,10 @@ function IndicatorProgressBar(props: IndicatorProgressBarProps) { const startValue: number = goalValue.value < baseValue.value ? isNormalized - ? baseValue.normalizedValue + ? baseValue.normalizedValue! : baseValue.value : isNormalized - ? goalValue.normalizedValue + ? goalValue.normalizedValue! : goalValue.value; const latestDate = lastValue.date; @@ -244,10 +244,10 @@ function IndicatorProgressBar(props: IndicatorProgressBarProps) { const goalDisplayValue = goalValue.value < baseValue.value ? isNormalized - ? goalValue.normalizedValue + ? goalValue.normalizedValue! : goalValue.value : isNormalized - ? baseValue.normalizedValue + ? baseValue.normalizedValue! : baseValue.value; const minPrecision = findPrecision([ @@ -317,7 +317,6 @@ function IndicatorProgressBar(props: IndicatorProgressBarProps) { ? Math.max(MIN_BAR_WIDTH, +roundedValues.goal * scale) : 0, }; - const reductionCounterFrom = 0; const reductionCounterTo = roundedValues.start - roundedValues.latest; // Animation length relative to animated bar length @@ -326,7 +325,7 @@ function IndicatorProgressBar(props: IndicatorProgressBarProps) { : 0; useEffect(() => { - const sequence = [ + const sequence: Segment[] = [ [ '.latest-text', { @@ -352,7 +351,6 @@ function IndicatorProgressBar(props: IndicatorProgressBarProps) { '.start-bar', { attrX: bars.w - roundedValues.start * scale, - width: roundedValues.start * scale, }, { duration: reductionCounterDuration }, ], @@ -495,7 +493,7 @@ function IndicatorProgressBar(props: IndicatorProgressBarProps) { className="start-bar" width={bars.w} y={startBar.y} - attrX={0} + x={0} height={barHeight - barMargin} fill={startColor} /> @@ -557,7 +555,12 @@ function IndicatorProgressBar(props: IndicatorProgressBarProps) { 120 ? 'start' : 'end'} > {t('to-reduce')} @@ -710,7 +713,7 @@ function IndicatorProgressBar(props: IndicatorProgressBarProps) { )} {theme.section.indicatorShowcase.linkToSource && ( - + {note} )}