Skip to content

Commit

Permalink
fix: Do not filter by subthemes on the server side
Browse files Browse the repository at this point in the history
  • Loading branch information
bprusinowski committed Oct 26, 2023
1 parent 467a17a commit 15d0b76
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 82 deletions.
127 changes: 66 additions & 61 deletions app/browser/dataset-browse.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Maybe } from "@graphql-tools/utils/types";
import { Plural, t, Trans } from "@lingui/macro";
import {
Box,
Expand All @@ -15,11 +14,11 @@ import { Reorder } from "framer-motion";
import orderBy from "lodash/orderBy";
import pickBy from "lodash/pickBy";
import sortBy from "lodash/sortBy";
import uniqBy from "lodash/uniqBy";
import Link from "next/link";
import { useRouter } from "next/router";
import { stringify } from "qs";
import React, { useMemo, useState } from "react";
import { UseQueryState } from "urql";

import Flex, { FlexProps } from "@/components/flex";
import { Checkbox, MinimalisticSelect, SearchField } from "@/components/form";
Expand All @@ -32,6 +31,7 @@ import {
} from "@/components/presence";
import Tag from "@/components/tag";
import useDisclosure from "@/components/use-disclosure";
import { SearchCube } from "@/domain/data";
import { truthy } from "@/domain/types";
import { useFormatDate } from "@/formatters";
import {
Expand All @@ -40,10 +40,12 @@ import {
SearchCubeResultOrder,
SearchCubesQuery,
useOrganizationsQuery,
useSubthemesQuery,
useThemesQuery,
} from "@/graphql/query-hooks";
import { DataCubePublicationStatus } from "@/graphql/resolver-types";
import {
DataCubePublicationStatus,
SearchCubeResult,
} from "@/graphql/resolver-types";
import SvgIcCategories from "@/icons/components/IcCategories";
import SvgIcClose from "@/icons/components/IcClose";
import SvgIcOrganisations from "@/icons/components/IcOrganisations";
Expand Down Expand Up @@ -116,10 +118,10 @@ export const SearchDatasetInput = ({

export const SearchDatasetControls = ({
browseState,
searchResult,
cubes,
}: {
browseState: BrowseState;
searchResult: Maybe<SearchCubesQuery>;
cubes: SearchCubeResult[];
}) => {
const {
inputRef,
Expand Down Expand Up @@ -166,10 +168,10 @@ export const SearchDatasetControls = ({
aria-live="polite"
data-testid="search-results-count"
>
{searchResult && searchResult.searchCubes.length > 0 && (
{cubes.length > 0 && (
<Plural
id="dataset.results"
value={searchResult.searchCubes.length}
value={cubes.length}
zero="No datasets"
one="# dataset"
other="# datasets"
Expand Down Expand Up @@ -330,9 +332,11 @@ const NavItem = ({
const newFilters = [...filters].filter((f) =>
level === 1 ? f.__typename !== next.__typename : true
);

if (level === 1) {
newFilters.push(next);
}

return (
"/browse/" + newFilters.map(encodeFilter).join("/") + `?${extraURLParams}`
);
Expand All @@ -350,12 +354,14 @@ const NavItem = ({
);
const nextIndex = filters.findIndex((f) => f.iri === next.iri);
const newFilters = nextIndex === 0 ? [] : filters.slice(0, 1);

return (
"/browse?" + newFilters.map(encodeFilter).join("&") + `&${extraURLParams}`
);
}, [includeDrafts, search, filters, next.iri]);

const classes = useStyles();

const removeFilterButton = (
<Link href={removeFilterPath} passHref legacyBehavior>
<ButtonBase
Expand All @@ -370,12 +376,14 @@ const NavItem = ({
</ButtonBase>
</Link>
);

const countChip =
count !== undefined ? (
<NavChip color={theme.countColor} backgroundColor={theme.countBg}>
{count}
</NavChip>
) : null;

return (
<MotionBox
{...accordionPresenceProps}
Expand Down Expand Up @@ -420,54 +428,44 @@ const NavItem = ({
);
};

const organizationIriToTermsetParentIri = {
"https://register.ld.admin.ch/opendataswiss/org/bundesamt-fur-umwelt-bafu":
"https://register.ld.admin.ch/foen/theme",
} as Record<string, string>;

export const Subthemes = ({
organization,
subthemes,
filters,
counts,
}: {
organization: DataCubeOrganization;
subthemes: SearchCube["subthemes"];
filters: BrowseFilter[];
counts: Record<string, number>;
}) => {
const termsetIri = organizationIriToTermsetParentIri[organization.iri];
const { dataSource } = useDataSourceStore();
const locale = useLocale();
const [{ data: subthemes }] = useSubthemesQuery({
variables: {
parentIri: termsetIri,
sourceType: dataSource.type,
sourceUrl: dataSource.url,
locale,
},
pause: !termsetIri,
});
const alphaSubthemes = useMemo(
() => sortBy(subthemes?.subthemes, (x) => x.label),
[subthemes]
);
const sortedSubthemes = useMemo(() => {
return sortBy(subthemes, (d) => d.label);
}, [subthemes]);

return (
<>
{alphaSubthemes.map((x) => {
const count = counts[x.iri];
{sortedSubthemes.map((d) => {
const count = counts[d.iri];

if (!count) {
return null;
}

const filter: BrowseFilter = {
__typename: "DataCubeAbout",
...d,
};

return (
<NavItem
key={x.iri}
next={x}
key={d.iri}
next={filter}
filters={filters}
theme={organizationNavItemTheme}
active={filters[filters.length - 1]?.iri === x.iri}
active={filters[filters.length - 1]?.iri === d.iri}
level={2}
count={count}
>
{x.label}
{d.label}
</NavItem>
);
})}
Expand Down Expand Up @@ -602,7 +600,7 @@ const NavSection = ({
);
};

export const SearchFilters = ({ data }: { data?: SearchCubesQuery }) => {
export const SearchFilters = ({ cubes }: { cubes: SearchCubeResult[] }) => {
const { dataSource } = useDataSourceStore();
const locale = useLocale();
const { filters } = useBrowseContext();
Expand All @@ -622,14 +620,14 @@ export const SearchFilters = ({ data }: { data?: SearchCubesQuery }) => {
});

const counts = useMemo(() => {
if (!data?.searchCubes) {
return {};
}

const result: Record<string, number> = {};

for (const { cube } of data.searchCubes) {
const countables = [...cube.themes, cube.creator].filter(truthy);
for (const { cube } of cubes) {
const countables = [
...cube.themes,
...cube.subthemes,
cube.creator,
].filter(truthy);

for (const { iri } of countables) {
if (iri) {
Expand All @@ -639,7 +637,7 @@ export const SearchFilters = ({ data }: { data?: SearchCubesQuery }) => {
}

return result;
}, [data?.searchCubes]);
}, [cubes]);

const themeFilter = filters.find(isAttrEqual("__typename", "DataCubeTheme"));
const orgFilter = filters.find(
Expand Down Expand Up @@ -703,6 +701,13 @@ export const SearchFilters = ({ data }: { data?: SearchCubesQuery }) => {
/>
) : null;

const subthemes = React.useMemo(() => {
return uniqBy(
cubes.flatMap((d) => d.cube.subthemes),
(d) => d.iri
);
}, [cubes]);

const orgNav =
displayedOrgs && displayedOrgs.length > 0 ? (
<NavSection
Expand All @@ -720,7 +725,7 @@ export const SearchFilters = ({ data }: { data?: SearchCubesQuery }) => {
extra={
orgFilter && filters[0] === orgFilter ? (
<Subthemes
organization={orgFilter}
subthemes={subthemes}
filters={filters}
counts={counts}
/>
Expand Down Expand Up @@ -757,12 +762,14 @@ export const SearchFilters = ({ data }: { data?: SearchCubesQuery }) => {
};

export const DatasetResults = ({
query,
fetching,
error,
cubes,
}: {
query: UseQueryState<SearchCubesQuery>;
fetching: boolean;
error: any;
cubes: SearchCubeResult[];
}) => {
const { fetching, data, error } = query;

if (fetching) {
return (
<Box sx={{ alignItems: "center" }}>
Expand All @@ -779,7 +786,7 @@ export const DatasetResults = ({
);
}

if ((data && data.searchCubes.length === 0) || !data) {
if (cubes.length === 0) {
return (
<Typography
variant="h2"
Expand All @@ -792,16 +799,14 @@ export const DatasetResults = ({

return (
<>
{data.searchCubes.map(
({ cube, highlightedTitle, highlightedDescription }) => (
<DatasetResult
key={cube.iri}
dataCube={cube}
highlightedTitle={highlightedTitle}
highlightedDescription={highlightedDescription}
/>
)
)}
{cubes.map(({ cube, highlightedTitle, highlightedDescription }) => (
<DatasetResult
key={cube.iri}
dataCube={cube}
highlightedTitle={highlightedTitle}
highlightedDescription={highlightedDescription}
/>
))}
</>
);
};
Expand Down
50 changes: 43 additions & 7 deletions app/browser/select-dataset-step.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ const SelectDatasetStepContent = () => {
return formatBackLink(router.query);
}, [router.query]);
// Use the debounced query value here only!
const [datacubesQuery] = useSearchCubesQuery({
const [{ data, fetching, error }] = useSearchCubesQuery({
variables: {
sourceType: configState.dataSource.type,
sourceUrl: configState.dataSource.url,
Expand All @@ -151,9 +151,12 @@ const SelectDatasetStepContent = () => {
order,
includeDrafts,
filters: filters
? filters.map((filter) => {
return { type: filter.__typename, value: filter.iri };
})
? filters
// Subtheme filters are used on the client side.
.filter((d) => d.__typename !== "DataCubeAbout")
.map((filter) => {
return { type: filter.__typename, value: filter.iri };
})
: [],
},
});
Expand All @@ -163,6 +166,35 @@ const SelectDatasetStepContent = () => {
datasetIri: dataset,
});

const { allCubes, cubes } = React.useMemo(() => {
if (fetching || error || (data && data.searchCubes.length === 0) || !data) {
return {
allCubes: [],
cubes: [],
};
}

const subthemeFilters = filters.filter(
(d) => d.__typename === "DataCubeAbout"
);

if (subthemeFilters.length === 0) {
return {
allCubes: data.searchCubes,
cubes: data.searchCubes,
};
}

const subthemes = subthemeFilters.map((d) => d.iri);

return {
allCubes: data.searchCubes,
cubes: data.searchCubes.filter((d) => {
return d.cube.subthemes.some((d) => subthemes.includes(d.iri));
}),
};
}, [data, error, fetching, filters]);

if (configState.state !== "SELECTING_DATASET") {
return null;
}
Expand Down Expand Up @@ -237,7 +269,7 @@ const SelectDatasetStepContent = () => {
</MotionBox>
) : (
<MotionBox key="search-filters" {...navPresenceProps}>
<SearchFilters data={datacubesQuery.data} />
<SearchFilters cubes={allCubes} />
</MotionBox>
)}
</AnimatePresence>
Expand Down Expand Up @@ -272,9 +304,13 @@ const SelectDatasetStepContent = () => {

<SearchDatasetControls
browseState={browseState}
searchResult={datacubesQuery.data}
cubes={cubes}
/>
<DatasetResults
fetching={fetching}
error={error}
cubes={cubes}
/>
<DatasetResults key="results" query={datacubesQuery} />
</MotionBox>
)}
</AnimatePresence>
Expand Down
4 changes: 4 additions & 0 deletions app/domain/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ export type SearchCube = {
iri: string;
label: string;
}[];
subthemes: {
iri: string;
label: string;
}[];
};

const xmlSchema = "http://www.w3.org/2001/XMLSchema#";
Expand Down
Loading

0 comments on commit 15d0b76

Please sign in to comment.