Skip to content

Commit

Permalink
Merge pull request #122 from ConductionNL/development
Browse files Browse the repository at this point in the history
Development to main, week 42
  • Loading branch information
remko48 authored Oct 23, 2023
2 parents 9fcfa61 + d04d611 commit fcad53d
Show file tree
Hide file tree
Showing 15 changed files with 447 additions and 123 deletions.
219 changes: 168 additions & 51 deletions pwa/package-lock.json

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions pwa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"private": true,
"description": "Product Website Template",
"author": "Conduction",
"keywords": ["gatsby"],
"keywords": [
"gatsby"
],
"scripts": {
"develop": "gatsby develop",
"start": "gatsby develop",
Expand All @@ -22,8 +24,8 @@
"prepare": "cd .. && husky install"
},
"dependencies": {
"@conduction/components": "2.2.17",
"@conduction/theme": "1.0.48",
"@conduction/components": "2.2.18",
"@conduction/theme": "1.0.50",
"@fortawesome/fontawesome-svg-core": "^6.1.1",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/react-fontawesome": "^0.1.18",
Expand Down Expand Up @@ -55,9 +57,10 @@
"@nl-design-system-unstable/zwolle-design-tokens": "^1.0.0-alpha.100",
"@parcel/watcher": "^2.3.0",
"@tabler/icons-react": "2.21.0",
"@types/qs": "^6.9.9",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"@utrecht/component-library-react": "^1.0.0-alpha.355",
"@utrecht/component-library-react": "^1.0.0-alpha.394",
"@utrecht/design-tokens": "^1.0.0-alpha.524",
"axios": "^0.25.0",
"clsx": "^1.1.1",
Expand All @@ -70,6 +73,7 @@
"i18next": "^21.6.16",
"jwt-decode": "^3.1.2",
"lodash": "^4.17.21",
"qs": "^6.11.2",
"react": "^18.2.0",
"react-collapsible": "^2.10.0",
"react-dom": "^18.2.0",
Expand Down
6 changes: 4 additions & 2 deletions pwa/src/apiService/resources/openWoo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ export default class OpenWoo {
this._send = send;
}

public getAll = async (filters: IFiltersContext, currentPage: number): Promise<any> => {
let endpoint = `/openWOO?extend[]=all${filtersToQueryParams(filters)}&_order[Publicatiedatum]=desc&_limit=${OPEN_WOO_LIMIT}&_page=${currentPage}`;
public getAll = async (filters: IFiltersContext, currentPage: number, limit: number): Promise<any> => {
let endpoint = `/openWOO?extend[]=all${filtersToQueryParams(
filters,
)}&_order[Publicatiedatum]=desc&_limit=${limit}&_page=${currentPage}`;

if (process.env.GATSBY_OIDN_NUMBER) {
endpoint += `&oidn=${process.env.GATSBY_OIDN_NUMBER}`;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.container {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
list-style-type: none;

padding: 0;
margin: 0;

user-select: none;
}
74 changes: 74 additions & 0 deletions pwa/src/components/paginationLimitSelect/PaginationLimitSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import * as React from "react";
import * as styles from "./PaginationLimitSelect.module.css";
import clsx from "clsx";
import { useForm } from "react-hook-form";
import { SelectSingle } from "@conduction/components";
import { IQueryLimitContext, QUERY_LIMIT_DEFAULT, useQueryLimitContext } from "../../context/queryLimit";
import { useTranslation } from "react-i18next";

interface PaginationLimitSelectProps {
queryLimitName: string;
layoutClassName?: string;
}

export const PaginationLimitSelectComponent: React.FC<PaginationLimitSelectProps> = ({
queryLimitName,
layoutClassName,
}) => {
const {
watch,
register,
control,
setValue,
formState: { errors },
} = useForm();
const { queryLimit, setQueryLimit } = useQueryLimitContext();
const { t } = useTranslation();

const watchLimit = watch("limit");

const value = queryLimit[queryLimitName as keyof IQueryLimitContext];

React.useEffect(() => {
if (!watchLimit) return;
if (parseInt(watchLimit.value) === value) return;

const selectedLimit = limitSelectOptions.find((limitOption) => limitOption.value === watchLimit.value);

if (selectedLimit) {
setQueryLimit({ ...queryLimit, [queryLimitName]: parseInt(selectedLimit.value) });
}
}, [watchLimit]);

React.useEffect(() => {
setValue(
"limit",
limitSelectOptions.find((limitOption) => limitOption.value === (value !== undefined && value.toString())),
);
}, []);

return (
<div className={clsx(styles.container, layoutClassName && layoutClassName)}>
<span>{t("Results per page")}:</span>
<SelectSingle
ariaLabel={t("Select result limit")}
{...{ register, errors, control }}
defaultValue={QUERY_LIMIT_DEFAULT}
name="limit"
options={limitSelectOptions}
menuPlacement="auto"
placeholder={t("Limit")}
/>
</div>
);
};

const limitSelectOptions = [
{ label: "6", value: "6" },
{ label: "9", value: "9" },
{ label: "12", value: "12" },
{ label: "21", value: "21" },
{ label: "30", value: "30" },
{ label: "60", value: "60" },
{ label: "120", value: "120" },
];
3 changes: 3 additions & 0 deletions pwa/src/context/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { defaultGatsbyContext, IGatsbyContext } from "./gatsby";
import { defaultFiltersContext, IFiltersContext } from "./filters";
import { defaultDisplayContext, IDisplayContext } from "./displays";
import { defaultPaginationContext, IPaginationContext } from "./pagination";
import { defaultQueryLimitContext, IQueryLimitContext } from "./queryLimit";

export interface IGlobalContext {
initiated: boolean;
gatsby: IGatsbyContext;
filters: IFiltersContext;
displays: IDisplayContext;
pagination: IPaginationContext;
queryLimit: IQueryLimitContext;
}

export const defaultGlobalContext: IGlobalContext = {
Expand All @@ -18,6 +20,7 @@ export const defaultGlobalContext: IGlobalContext = {
filters: defaultFiltersContext,
displays: defaultDisplayContext,
pagination: defaultPaginationContext,
queryLimit: defaultQueryLimitContext,
};

export const GlobalContext = React.createContext<
Expand Down
24 changes: 24 additions & 0 deletions pwa/src/context/queryLimit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from "react";
import { GlobalContext } from "./global";

export const QUERY_LIMIT_DEFAULT = 12;

export interface IQueryLimitContext {
openWooObjectsQueryLimit: number;
}

export const defaultQueryLimitContext: IQueryLimitContext = {
openWooObjectsQueryLimit: QUERY_LIMIT_DEFAULT,
};

export const useQueryLimitContext = () => {
const [globalContext, setGlobalContext] = React.useContext(GlobalContext);

const queryLimit: IQueryLimitContext = globalContext.queryLimit;

const setQueryLimit = (query: IQueryLimitContext) => {
setGlobalContext((context) => ({ ...context, queryLimit: { ...globalContext.queryLimit, ...query } }));
};

return { setQueryLimit, queryLimit };
};
4 changes: 2 additions & 2 deletions pwa/src/hooks/openWoo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { IFiltersContext } from "../context/filters";
export const useOpenWoo = (queryClient: QueryClient) => {
const API: APIService | null = React.useContext(APIContext);

const getAll = (filters: IFiltersContext, currentPage: number) =>
useQuery<any, Error>(["OpenWoo", filters, currentPage], () => API?.OpenWoo.getAll(filters, currentPage), {
const getAll = (filters: IFiltersContext, currentPage: number, limit: number) =>
useQuery<any, Error>(["OpenWoo", filters, currentPage, limit], () => API?.OpenWoo.getAll(filters, currentPage, limit), {
onError: (error) => {
console.warn(error.message);
},
Expand Down
52 changes: 32 additions & 20 deletions pwa/src/services/filtersToQueryParams.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,43 @@
export const filtersToQueryParams = (filters: any): string => {
Object.keys(filters)
.filter((key) => filterKeysToRemove.includes(key))
.forEach((key) => {
delete filters[key];
});
const cleanedFilters = Object.fromEntries(
Object.entries(filters).filter(([key]) => !filterKeysToRemove.includes(key)),
);

let params = "";
const params = Object.entries(cleanedFilters)
.map(([key, value]) => {
if (!value) return null;

for (const [key, value] of Object.entries(filters)) {
if (!value) continue;
const formattedValue = Array.isArray(value)
? value.map((v: string) => v.replace(/\s+/g, "_")).join(`&${key}[]=`)
: (value as string).replace(/\s+/g, "_");

if (typeof value === "string") {
params += `&${key}=${value}`;
}
return `${Array.isArray(value) ? `${key}[]` : key}=${formattedValue}`;
})
.filter(Boolean)
.join("&");

if (Array.isArray(value)) {
let arrayParams = "";
return params ? `&${params}` : "";
};

export const filtersToUrlQueryParams = (filters: Record<string, any>): string => {
const cleanedFilters = Object.fromEntries(
Object.entries(filters).filter(([key]) => !filterKeysToRemove.includes(key)),
);

const params = Object.entries(cleanedFilters)
.map(([key, value]) => {
if (!value) return null;

value.forEach((value) => {
arrayParams += `&${key}[]=${value}`;
});
const formattedValue = Array.isArray(value)
? value.map((v: string) => v.replace(/\s+/g, "_")).join(`&${key}[]=`)
: (value as string).replace(/\s+/g, "_");

params += arrayParams;
}
}
return `${Array.isArray(value) ? `${key}[]` : key}=${formattedValue}`;
})
.filter(Boolean)
.join("&");

return params;
return params ? `?${params}` : "";
};

const filterKeysToRemove: string[] = [];
6 changes: 3 additions & 3 deletions pwa/src/templates/landing/LandingTemplate.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
margin-block-end: var(--utrecht-space-block-lg);
}

.header1 {
margin-block-start: 0px;
margin-block-end: 0px;
.pagination {
display: flex;
justify-content: space-between;
}
24 changes: 16 additions & 8 deletions pwa/src/templates/landing/LandingTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,24 @@ import { QueryClient } from "react-query";
import { Pagination } from "@conduction/components";
import { usePaginationContext } from "../../context/pagination";
import { useTranslation } from "react-i18next";
import { useQueryLimitContext } from "../../context/queryLimit";
import { PaginationLimitSelectComponent } from "../../components/paginationLimitSelect/PaginationLimitSelect";

export const LandingTemplate: React.FC = () => {
const { currentPage, setCurrentPage } = usePaginationContext();
const { filters } = useFiltersContext();
const { t } = useTranslation();
const { queryLimit } = useQueryLimitContext();

const queryClient = new QueryClient();
const getItems = useOpenWoo(queryClient).getAll(filters, currentPage);
const getItems = useOpenWoo(queryClient).getAll(filters, currentPage, queryLimit.openWooObjectsQueryLimit);

React.useEffect(() => {
setCurrentPage(1);
}, [queryLimit.openWooObjectsQueryLimit]);

return (
<>
<h1 className={styles.header1}></h1>
<JumbotronTemplate />

<Page>
Expand All @@ -33,12 +39,14 @@ export const LandingTemplate: React.FC = () => {
{getItems.data?.results && getItems.data?.results?.length > 0 && (
<div id="mainContent">
<ResultsDisplayTemplate displayKey="landing-results" requests={getItems.data.results} />

<Pagination
ariaLabels={{ previousPage: t("Previous page"), nextPage: t("Next page"), page: t("Page") }}
totalPages={getItems.data.pages}
{...{ currentPage, setCurrentPage }}
/>
<div className={styles.pagination}>
<Pagination
ariaLabels={{ previousPage: t("Previous page"), nextPage: t("Next page"), page: t("Page") }}
totalPages={getItems.data.pages}
{...{ currentPage, setCurrentPage }}
/>
<PaginationLimitSelectComponent queryLimitName={"openWooObjectsQueryLimit"} />
</div>
</div>
)}
{getItems.isLoading && <Skeleton height={"200px"} />}
Expand Down
Loading

0 comments on commit fcad53d

Please sign in to comment.