Skip to content

Commit

Permalink
Merge pull request #474 from GenomicDataInfrastructure/fix-card-ui
Browse files Browse the repository at this point in the history
feat: extract card component for consistency + minor ui fixes
  • Loading branch information
brunopacheco1 authored Oct 8, 2024
2 parents af93ca9 + abef59e commit 8ad88ec
Show file tree
Hide file tree
Showing 21 changed files with 546 additions and 290 deletions.
4 changes: 4 additions & 0 deletions src/app/applications/[id]/TermsAcceptance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ export default function TermsAcceptance() {
}
};

if (!application?.licenses || application?.licenses.length === 0) {
return <p>No terms and conditions have been defined.</p>;
}

return (
<div className="text-base">
{alert && (
Expand Down
18 changes: 15 additions & 3 deletions src/app/applications/[id]/sidebarItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@
//
// SPDX-License-Identifier: Apache-2.0

import DatasetList from "@/app/requests/applications/DatasetList";
import { createTextItem, SidebarItem } from "@/components/Sidebar";
import { RetrievedApplication } from "@/types/application.types";
import { formatApplicationProp } from "@/utils/application";
import { formatDateTime } from "@/utils/formatDate";
import { faHistory, faUser } from "@fortawesome/free-solid-svg-icons";
import {
faDatabase,
faHistory,
faUser,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import TermsAcceptance from "./TermsAcceptance";
import { getLabelName } from "@/utils/getLabelName";

export function createApplicationSidebarItems(
application: RetrievedApplication
Expand All @@ -19,7 +23,15 @@ export function createApplicationSidebarItems(
return [
{
label: "Datasets",
value: <DatasetList datasets={datasets} className="gap-x-6" />,
value: datasets.map((dataset, index) => (
<span
className="mb-3 flex items-center gap-x-6"
key={`${dataset.id}-${index}`}
>
<FontAwesomeIcon icon={faDatabase} className="text-primary" />
<p className="break-words">{getLabelName(dataset.title)}</p>
</span>
)),
},
{
label: "Participants",
Expand Down
2 changes: 1 addition & 1 deletion src/app/basket/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { useDatasetBasket } from "@/providers/DatasetBasketProvider";
import { createApplication } from "@/services/daam/index.client";
import { faPaperPlane, faPlusCircle } from "@fortawesome/free-solid-svg-icons";
import { signIn, useSession } from "next-auth/react";
import DatasetList from "../../components/DatasetList";
import DatasetList from "../datasets/DatasetList";
import { AxiosError } from "axios";

export default function Page() {
Expand Down
64 changes: 64 additions & 0 deletions src/app/datasets/DatasetCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-FileCopyrightText: 2024 PNED G.I.E.
//
// SPDX-License-Identifier: Apache-2.0

import Button from "@/components/Button";
import { useWindowSize } from "@/hooks";
import { useDatasetBasket } from "@/providers/DatasetBasketProvider";
import { SearchedDataset } from "@/services/discovery/types/dataset.types";
import { truncateDescription } from "@/utils/textProcessing";
import { faMinusCircle, faPlusCircle } from "@fortawesome/free-solid-svg-icons";
import Card, { CardItem } from "../../components/Card";

type DatasetCardProps = {
dataset: SearchedDataset;
cardItems: CardItem[];
};

function DatasetCard({ dataset, cardItems }: Readonly<DatasetCardProps>) {
const screenSize = useWindowSize();
const truncatedDesc = dataset.description
? truncateDescription(dataset.description, screenSize)
: null;

const { basket, addDatasetToBasket, removeDatasetFromBasket, isLoading } =
useDatasetBasket();

const isInBasket = basket.some((ds) => ds.id === dataset.id);

const toggleDatasetInBasket = (e: React.MouseEvent) => {
e.preventDefault();
if (isInBasket) {
removeDatasetFromBasket(dataset);
} else {
addDatasetToBasket(dataset);
}
};

const hasIdentifier = !!dataset.identifier;
const buttonDisabled = isLoading || !hasIdentifier;

return (
<Card
url={`/datasets/${dataset.id}`}
title={dataset.title}
subTitles={dataset.themes?.map((theme) => theme.label)}
description={truncatedDesc || "No description available"}
cardItems={cardItems}
keywords={dataset.keywords?.map((keyword) => keyword.label)}
button={
<Button
text={isInBasket ? "Remove from basket" : "Add to basket"}
icon={isInBasket ? faMinusCircle : faPlusCircle}
onClick={toggleDatasetInBasket}
type={isInBasket ? "warning" : "primary"}
disabled={buttonDisabled}
flex={true}
className="text-xs sm:text-base"
/>
}
/>
);
}

export default DatasetCard;
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
//
// SPDX-License-Identifier: Apache-2.0

import DatasetCard from "@/app/datasets/DatasetCard";
import { createDatasetCardItems } from "@/app/datasets/datasetCardItems";
import List from "@/components/List";
import ListItem from "@/components/List/ListItem";
import { SearchedDataset } from "@/services/discovery/types/dataset.types";
import DatasetCard from "@/components/DatasetCard";

type DatasetListProps = {
datasets: SearchedDataset[];
Expand All @@ -19,7 +20,10 @@ function DatasetList({ datasets }: Readonly<DatasetListProps>) {
key={dataset.id}
className="bg-white mb-4 flex items-center justify-center px-2 rounded-lg shadow-lg border-b-4 border-b-[#B5BFC4] hover:border-b-secondary transition hover:bg-gray-50"
>
<DatasetCard dataset={dataset} />
<DatasetCard
dataset={dataset}
cardItems={createDatasetCardItems(dataset)}
/>
</ListItem>
))}
</List>
Expand Down
2 changes: 1 addition & 1 deletion src/app/datasets/DatasetListContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import Error from "@/app/error";
import PaginationContainer from "@/components/PaginationContainer";
import DatasetList from "../../components/DatasetList";
import DatasetList from "./DatasetList";
import {
DATASET_PER_PAGE,
useDatasets,
Expand Down
69 changes: 69 additions & 0 deletions src/app/datasets/__tests__/datasetCardItems.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// SPDX-FileCopyrightText: 2024 PNED G.I.E.
//
// SPDX-License-Identifier: Apache-2.0

import { SearchedDataset } from "@/services/discovery/types/dataset.types";
import { createDatasetCardItems } from "../datasetCardItems";

describe("datasetCardItems", () => {
beforeEach(() => {
global.window = {} as unknown as Window & typeof globalThis;
});

afterEach(() => {
global.window = undefined as unknown as Window & typeof globalThis;
});

it("should return dataset card items", () => {
const dataset: SearchedDataset = {
id: "1",
title: "",
description: "dataset1 description",
themes: [{ value: "theme1", label: "theme1" }],
keywords: [
{
label: "keyword1",
value: "keyword1",
},
{
label: "keyword2",
value: "keyword2",
},
],
distributions: [
{
id: "r",
title: "distribution1",
description: "distribution1 description",
format: {
label: "format1",
value: "format1",
},
licenses: [],
createdAt: "2022-01-01T00:00:00.000Z",
modifiedAt: "2022-01-01T00:00:00.000Z",
uri: "distribution1",
},
],
organization: {
id: "1",
title: "organization1",
imageUrl: "",
numberOfDatasets: 0,
name: "organization1",
description: "organization1 description",
},
createdAt: "2024-03-01T00:00:00.000Z",
modifiedAt: "",
recordsCount: 21,
};

const items = createDatasetCardItems(dataset);
expect(items.length).toBe(5);
expect(items[0].text).toBe("Created on 1 March 2024");
expect(items[1].text).toBe("");
expect(items[2].text).toBe("Published by organization1");
expect(items[3].text).toBe("1 Distribution");
expect(items[4].text).toBe("21 Records");
});
});
57 changes: 57 additions & 0 deletions src/app/datasets/datasetCardItems.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// SPDX-FileCopyrightText: 2024 PNED G.I.E.
//
// SPDX-License-Identifier: Apache-2.0

import { CardItem } from "@/components/Card";
import { SearchedDataset } from "@/services/discovery/types/dataset.types";
import { formatDate } from "@/utils/formatDate";
import {
faBookBookmark,
faCalendarAlt,
faFile,
faSyncAlt,
faUser,
} from "@fortawesome/free-solid-svg-icons";

export function createDatasetCardItems(dataset: SearchedDataset): CardItem[] {
return [
{
text:
(dataset.createdAt && `Created on ${formatDate(dataset.createdAt)}`) ||
"",
icon: faCalendarAlt,
},
{
text:
(dataset.modifiedAt &&
`Modified on ${formatDate(dataset.modifiedAt)}`) ||
"",
icon: faSyncAlt,
},
{
text:
(dataset.organization?.title &&
`Published by ${dataset.organization.title}`) ||
"",
icon: faUser,
},
{
text:
(dataset.distributions?.length &&
(dataset.distributions.length === 1
? "1 Distribution"
: `${dataset.distributions.length} Distributions`)) ||
"",
icon: faFile,
},
{
text:
(dataset.recordsCount &&
(dataset.recordsCount === 1
? "1 Record"
: `${dataset.recordsCount} Records`)) ||
"",
icon: faBookBookmark,
},
];
}
23 changes: 23 additions & 0 deletions src/app/requests/applications/ApplicationCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-FileCopyrightText: 2024 PNED G.I.E.
//
// SPDX-License-Identifier: Apache-2.0

import { ListedApplication } from "@/types/application.types";
import Card from "@/components/Card";
import { createApplicationCardItems } from "./applicationCardItems";

export default function ApplicationCard({
application,
}: Readonly<{
application: ListedApplication;
}>) {
return (
<Card
url={`/applications/${application.id}`}
title={application.title}
subTitles={[application.currentState.split("/").pop() || ""]}
description={application.description}
cardItems={createApplicationCardItems(application)}
/>
);
}
66 changes: 0 additions & 66 deletions src/app/requests/applications/ApplicationItem.tsx

This file was deleted.

Loading

0 comments on commit 8ad88ec

Please sign in to comment.