Skip to content

Commit

Permalink
Merge pull request #441 from OpenCatalogi/feature/OP-240/Application-…
Browse files Browse the repository at this point in the history
…Component

feature/OP-240/Application-Component
  • Loading branch information
remko48 authored Feb 29, 2024
2 parents 532e205 + 6f7dda0 commit e7df02c
Show file tree
Hide file tree
Showing 31 changed files with 457 additions and 124 deletions.
2 changes: 1 addition & 1 deletion publiccode.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
publiccodeYmlVersion: "0.3"
name: "OpenCatalogi web-app"
applicationSuite: "opencatalogi"
applicationSuite: "OpenCatalogi Applicatie"
url: https://github.com/OpenCatalogi/web-app
landingURL: "https://github.com/OpenCatalogi/web-app"
isBasedOn: null
Expand Down
30 changes: 24 additions & 6 deletions pwa/src/apiService/resources/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,38 @@ export default class Search {
this._instance = _instance;
}

public getSearch = async (filters: IFiltersContext, currentPage: number, limit: number): Promise<any> => {
let endpoint = `/search?page=${currentPage}&limit=${limit}&extend[]=all${filtersToQueryParams(
filters,
)}&embedded.rating.rating[>%3D]=${filters.rating}`;
public getSearch = async (
filters: IFiltersContext,
currentPage: number,
limit: number,
ratingFilter: string,
): Promise<any> => {
let endpoint = `/search?page=${currentPage}&limit=${limit}&extend[]=all${filtersToQueryParams(filters)}`;

if (ratingFilter === "OpenCatalogi") {
endpoint += `&embedded.rating.rating[>%3D]=${filters.rating}`;
}

if (filters.orderRating === true) {
if (filters.orderRating === true && ratingFilter === "OpenCatalogi") {
endpoint += "&order[embedded.rating.rating]=desc";
}

if (ratingFilter === "Commonground") {
endpoint += `&embedded.nl.embedded.commonground.rating[>%3D]=${filters.ratingCommonground}`;
}

if (filters.orderRating === true && ratingFilter === "Commonground") {
endpoint += "&order[embedded.nl.embedded.commonground.rating]=desc";
}

if (filters.isForked === true) {
endpoint += "&isBasedOn=IS NULL";
}

if (window.sessionStorage.getItem("GITHUB_ORGANIZATION_URL") !== "" && window.sessionStorage.getItem("GITHUB_ORGANIZATION_URL") !== "false") {
if (
window.sessionStorage.getItem("GITHUB_ORGANIZATION_URL") !== "" &&
window.sessionStorage.getItem("GITHUB_ORGANIZATION_URL") !== "false"
) {
endpoint += `&embedded.url.embedded.organisation.github=${window.sessionStorage.getItem(
"GITHUB_ORGANIZATION_URL",
)}`;
Expand Down
9 changes: 7 additions & 2 deletions pwa/src/components/applicationCard/ApplicationCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from "react";
import * as styles from "./ApplicationCard.module.css";
import clsx from "clsx";
import { DataBadge, Icon, Link, Paragraph } from "@utrecht/component-library-react/dist/css-module";
import { useTranslation } from "react-i18next";
import { IconArrowRight } from "@tabler/icons-react";
Expand All @@ -19,13 +20,17 @@ export interface ApplicationCardProps {
organization?: string;
githubLink?: string;
};
layoutClassName?: string;
}

export const ApplicationCard: React.FC<ApplicationCardProps> = ({ title, description, tags }) => {
export const ApplicationCard: React.FC<ApplicationCardProps> = ({ title, description, tags, layoutClassName }) => {
const { t } = useTranslation();

return (
<CardWrapper className={styles.container} onClick={() => navigate(title.href)}>
<CardWrapper
className={clsx([styles.container, layoutClassName && layoutClassName])}
onClick={() => navigate(title.href)}
>
<CardHeader className={styles.cardHeader}>
<CardHeaderTitle>
<Link className={styles.titleLink} onClick={() => navigate(title.href)}>
Expand Down
36 changes: 36 additions & 0 deletions pwa/src/components/componentCard/ComponentCard.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,14 @@
align-self: center;
flex: 1;
}

.ratingIndicatorContainer {
min-height: 55px;
}

.commongroundRating {
min-height: 55px;
}
}

@media only screen and (min-width: 576px) {
Expand All @@ -97,9 +102,40 @@
align-self: center;
flex: 1;
}

.ratingIndicatorContainer {
min-height: 55px;
}

.commongroundRating {
min-height: 55px;
}
}

.commongroundRating {
border-radius: 50%;
height: 70px;
width: 70px;
justify-content: center;
align-items: center;
display: flex;
}

/* Colors of commonground rating */

.goldRating {
background-color: #d4af37;
color: #ffffff;
}

.silverRating {
background: #bcc6cc;
color: #ffffff;
}

.bronzeRating {
background: #a97142;
color: #ffffff;
}

/* Colors of the 5 layers */
Expand Down
43 changes: 35 additions & 8 deletions pwa/src/components/componentCard/ComponentCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as React from "react";
import * as styles from "./ComponentCard.module.css";
import { DataBadge, Icon, Link, Paragraph } from "@utrecht/component-library-react/dist/css-module";
import _ from "lodash";
import clsx from "clsx";
import { DataBadge, Icon, Link, Paragraph } from "@utrecht/component-library-react/dist/css-module";
import { categories as _categories, TCategories } from "../../data/categories";
import { useTranslation } from "react-i18next";
import { IconArrowRight } from "@tabler/icons-react";
Expand All @@ -12,6 +13,7 @@ import { TOOLTIP_ID } from "../../layout/Layout";
import { CardHeader, CardHeaderTitle, CardWrapper } from "@conduction/components";
import { navigate } from "gatsby";
import { RatingIndicatorTemplate } from "../../templates/templateParts/ratingIndicator/RatingIndicatorTemplate";
import { getCommongroundRating } from "../../services/getCommongroundRating";

export interface ComponentCardProps {
title: {
Expand All @@ -26,6 +28,9 @@ export interface ComponentCardProps {
rating: number;
maxRating: number;
};
ratingCommonground?: {
rating: number;
};
status?: string;
installations: string;
organization: {
Expand All @@ -40,6 +45,8 @@ export interface ComponentCardProps {
export const ComponentCard: React.FC<ComponentCardProps> = ({ title, layer, categories, description, tags }) => {
const { t } = useTranslation();

const ratingFilter = window.sessionStorage.getItem("FILTER_RATING");

const _layer: TCategories = t(_.upperFirst(layer));

const __categories =
Expand Down Expand Up @@ -149,13 +156,33 @@ export const ComponentCard: React.FC<ComponentCardProps> = ({ title, layer, cate
</div>
</div>
<div className={styles.ratingContainer}>
{tags.rating && (
<RatingIndicatorTemplate
layoutClassName={styles.ratingIndicatorContainer}
maxRating={tags.rating?.maxRating}
rating={tags.rating?.rating}
/>
)}
<>
{ratingFilter === "OpenCatalogi" && (
<>
{tags.rating && tags.rating?.rating && (
<RatingIndicatorTemplate
layoutClassName={styles.ratingIndicatorContainer}
maxRating={tags.rating?.maxRating}
rating={tags.rating?.rating}
/>
)}
</>
)}
{ratingFilter === "Commonground" && (
<>
{tags.ratingCommonground && tags.ratingCommonground?.rating && (
<div
className={clsx(
styles[_.camelCase(t(`${getCommongroundRating(tags.ratingCommonground.rating ?? "0")} rating`))],
styles.commongroundRating,
)}
>
{t(getCommongroundRating(tags.ratingCommonground.rating))}
</div>
)}
</>
)}
</>
</div>
</div>
</CardWrapper>
Expand Down
2 changes: 2 additions & 0 deletions pwa/src/context/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface IFiltersContext {
orderRating: boolean;
rating: number;
organizationSearch?: string;
ratingCommonground: number;

_search?: string;
softwareType?: string;
Expand Down Expand Up @@ -34,6 +35,7 @@ export const defaultFiltersContext: IFiltersContext = {
orderRating: true,
developmentStatus: "stable",
rating: 16,
ratingCommonground: 1,
};

export const useFiltersContext = () => {
Expand Down
4 changes: 4 additions & 0 deletions pwa/src/context/queryLimit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@ export const QUERY_LIMIT_DEFAULT = 10;
export interface IQueryLimitContext {
previousComponentsSearchQueryLimit: number;
componentsSearchQueryLimit: number;
previousOrganizationsQueryLimit: number;
organizationsQueryLimit: number;
previousApplicationsQueryLimit: number;
applicationsQueryLimit: number;
}

export const defaultQueryLimitContext: IQueryLimitContext = {
previousComponentsSearchQueryLimit: QUERY_LIMIT_DEFAULT,
componentsSearchQueryLimit: QUERY_LIMIT_DEFAULT,
previousOrganizationsQueryLimit: QUERY_LIMIT_DEFAULT,
organizationsQueryLimit: QUERY_LIMIT_DEFAULT,
previousApplicationsQueryLimit: QUERY_LIMIT_DEFAULT,
applicationsQueryLimit: QUERY_LIMIT_DEFAULT,
};

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

const getSearch = (filters: IFiltersContext, currentPage: number, limit: number) =>
const getSearch = (filters: IFiltersContext, currentPage: number, limit: number, ratingFilter: string) =>
useQuery<any, Error>(
["search", filters, currentPage, limit],
() => API?.Search.getSearch(filters, currentPage, limit),
() => API?.Search.getSearch(filters, currentPage, limit, ratingFilter),
{
onError: (error) => {
throw new Error(error.message);
Expand Down
2 changes: 2 additions & 0 deletions pwa/src/hooks/useEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export const useEnvironment = () => {
window.sessionStorage.setItem("FOOTER_CONTENT", process.env.GATSBY_FOOTER_CONTENT ?? "");
window.sessionStorage.setItem("FOOTER_CONTENT_HEADER", process.env.GATSBY_FOOTER_CONTENT_HEADER ?? "");
window.sessionStorage.setItem("OPTIONAL_START_PAGE", process.env.GATSBY_OPTIONAL_START_PAGE ?? "");
window.sessionStorage.setItem("FILTER_RATING", process.env.GATSBY_FILTER_RATING ?? "Commonground");

updateSessionStorage();
};
Expand Down Expand Up @@ -88,6 +89,7 @@ export const useEnvironment = () => {
window.sessionStorage.setItem("FOOTER_CONTENT", config.GATSBY_FOOTER_CONTENT ?? "");
window.sessionStorage.setItem("FOOTER_CONTENT_HEADER", config.GATSBY_FOOTER_CONTENT_HEADER ?? "");
window.sessionStorage.setItem("OPTIONAL_START_PAGE", config.GATSBY_OPTIONAL_START_PAGE ?? "");
window.sessionStorage.setItem("FILTER_RATING", config.GATSBY_FILTER_RATING ?? "OpenCatalogi");

updateSessionStorage();
};
Expand Down
2 changes: 1 addition & 1 deletion pwa/src/layout/Head.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const Head: React.FC = () => {
<Helmet
title={window.sessionStorage.getItem("PAGE_TITLE") ?? "OpenCatalogi"}
bodyAttributes={{
class: window.sessionStorage.getItem("NL_DESIGN_THEME_CLASSNAME") ?? "conduction-theme",
class: theme,
}}
/>
);
Expand Down
7 changes: 6 additions & 1 deletion pwa/src/services/filtersToQueryParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,19 @@ export const filtersToQueryParams = (filters: any): string => {
params += "&isBasedOn=IS NULL";
break;
case "orderRating":
params += "&order[embedded.rating.rating]=desc";
window.sessionStorage.getItem("FILTER_RATING") === "Commonground"
? (params += "&order[embedded.nl.embedded.commonground.rating]=desc")
: (params += "&order[embedded.rating.rating]=desc");
break;
case "componentsCurrentPage":
params += "";
break;
case "rating":
params += "";
break;
case "ratingCommonground":
params += "";
break;

default:
params += `&${key}=${value}`;
Expand Down
14 changes: 14 additions & 0 deletions pwa/src/services/getCommongroundRating.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const getCommongroundRating = (rating: number): string => {
switch (rating) {
case 0:
return "N.V.T";
case 1:
return "Bronze";
case 2:
return "Silver";
case 3:
return "Gold";
default:
return "N.V.T";
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { faExternalLink } from "@fortawesome/free-solid-svg-icons";
export const ApplicationsTemplate: React.FC = () => {
const { t } = useTranslation();
const { filters } = useFiltersContext();
const { queryLimit } = useQueryLimitContext();
const { queryLimit, setQueryLimit } = useQueryLimitContext();
const { pagination, setPagination } = usePaginationContext();

const queryClient = new QueryClient();
Expand All @@ -32,7 +32,10 @@ export const ApplicationsTemplate: React.FC = () => {
);

React.useEffect(() => {
if (queryLimit.previousApplicationsQueryLimit === queryLimit.applicationsQueryLimit) return;

setPagination({ ...pagination, applicationCurrentPage: 1 });
setQueryLimit({ ...queryLimit, previousApplicationsQueryLimit: queryLimit.applicationsQueryLimit });
}, [queryLimit.applicationsQueryLimit]);

return (
Expand Down
Loading

0 comments on commit e7df02c

Please sign in to comment.