Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Organized all labels into categories #900

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions components/Labels/FilterLabelBox.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
display: flex;
flex-direction: column;

width: min(90vw, 600px);
width: min(90vw, 1300px);
height: 80vh;

animation-name: fade-in;
Expand Down Expand Up @@ -46,15 +46,34 @@
flex-direction: column;
justify-content: left;
overflow: auto;
flex-grow: 1;
}

.labelCounter {
font-size: 16px;
}

.labelContainer {
height: 100px;
display: flex;
flex-wrap: wrap;
background-color: $equinor_LIGHT_GRAY;
padding: 16px;
gap: 20px;
flex-grow: 1;
overflow: auto;
}

@media (max-width: 1024px) {
.labelContainer {
flex-direction: column;
}
}

@media (min-width: 1025px) {
.labelContainer {
flex-direction: row;
flex-wrap: wrap;
}
}

.button:hover {
Expand Down
48 changes: 29 additions & 19 deletions components/Labels/FilterLabelBox.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { Button, Chip, Icon, Search } from "@equinor/eds-core-react";
import { Button, Icon, Search } from "@equinor/eds-core-react";
import { useState } from "react";

import { close } from "@equinor/eds-icons";
import { debounce } from "utils/debounce";
import { getLabels } from "services/labelsApi";
import { getUpdatedLabel } from "utils/getUpdatedLabel";
import styles from "./FilterLabelBox.module.scss";
import { unknownErrorToString } from "utils/isError";
import { useQuery } from "react-query";
import { useRouter } from "next/router";
import LabelCategory from "./LabelCategory";
import { toggleLabels } from "@/utils/toggleLabels";
import { getCategorizedLabels } from "@/utils/getCategorizedLabels";

export function FilterLabelBox(props: { handleClose: () => void }) {
const [searchText, setSearchText] = useState("");
Expand Down Expand Up @@ -82,8 +84,12 @@ function LabelSection(props: {
const router = useRouter();

// rl stands for "required label"
const handleClick = (selectedLabelId: string) => {
const labelIdArray = getUpdatedLabel(selectedLabelId, router.query.rl);
const handleLabels = (selectedLabelId: string, isSelect: boolean) => {
const labelIdArray = toggleLabels(
selectedLabelId,
router.query.rl,
isSelect
);
void router.replace({
query: { ...router.query, rl: labelIdArray },
});
Expand All @@ -103,24 +109,28 @@ function LabelSection(props: {
return <p>{unknownErrorToString(error)}</p>;
}

const [categorisedLabels, noOfLabels] = getCategorizedLabels(labels);

return (
<div className={styles.labelSection}>
<p className={styles.labelCounter}>
{`${labels.length}`} {labels.length == 1 ? "label" : "labels"}{" "}
discovered
</p>

<div>
<p className={styles.labelCounter}>
{`${noOfLabels}`} {noOfLabels == 1 ? "label" : "labels"} discovered
</p>
</div>
<div className={styles.labelContainer}>
{labels.map((label: any) => (
<Chip
key={label.id}
variant={isActive(label.id.toString()) ? "active" : undefined}
style={{ marginRight: "5px", marginBottom: "10px" }}
onClick={() => handleClick(label.id.toString())}
>
{label.text}
</Chip>
))}
{categorisedLabels &&
Object.keys(categorisedLabels).map((categoryName) => {
return (
<LabelCategory
key={categoryName}
categoryName={categoryName}
labels={categorisedLabels[categoryName]}
isActive={isActive}
handleLabels={handleLabels}
/>
);
})}
</div>
</div>
);
Expand Down
25 changes: 25 additions & 0 deletions components/Labels/LabelCategory.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@import "styles/_variables.scss";

.categoryContainer {
gap: 8px;
display: flex;
flex: 1;
flex-direction: column;
}

.labelsContainer {
border-radius: 4px;
padding: 16px;
gap: 8px;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
background-color: white;
flex-grow: 1;
}

.categoryTitle {
font-size: 12px;
font-weight: 400;
color: $text-default;
}
48 changes: 48 additions & 0 deletions components/Labels/LabelCategory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Chip, Typography } from "@equinor/eds-core-react";
import React from "react";
import styles from "./LabelCategory.module.scss";
import { ProcessLabel } from "@/types/ProcessLabel";

const chipInlineStyle: React.CSSProperties = {
marginRight: "5px",
marginBottom: "10px",
height: "auto",
gridTemplateColumns: "auto",
whiteSpace: "normal",
wordBreak: "break-word",
};

export default function LabelCategory(props: {
categoryName: string;
labels: ProcessLabel[];
isActive: (id: string) => boolean | undefined;
handleLabels: (id: string, isSelect: boolean) => void;
}) {
const { categoryName, labels, isActive, handleLabels } = props;

return (
<div className={styles.categoryContainer}>
<Typography className={styles.categoryTitle}>{categoryName}</Typography>
<div className={styles.labelsContainer}>
{labels.map((label: any) => {
const isLabelActive = isActive(label.id.toString());
return (
<Chip
key={label.id}
variant={isLabelActive ? "active" : undefined}
style={chipInlineStyle}
onClick={() => handleLabels(label.id.toString(), true)}
onDelete={
isLabelActive
? () => handleLabels(label.id.toString(), false)
: undefined
}
>
{label.text}
</Chip>
);
})}
</div>
</div>
);
}
5 changes: 5 additions & 0 deletions types/LabelsCategories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const labelsCategories = {
l1LevelOrganisation: "L1 Level Organisations",
functionalArea: "Functional Areas",
assets: "Assets",
};
1 change: 1 addition & 0 deletions types/ProcessLabel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export type ProcessLabel = {
id: number;
text: string;
category: string;
};
28 changes: 28 additions & 0 deletions utils/getCategorizedLabels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { labelsCategories } from "@/types/LabelsCategories";
import { ProcessLabel } from "@/types/ProcessLabel";

export function getCategorizedLabels(labels: ProcessLabel[]) {
const { l1LevelOrganisation, functionalArea, assets } = labelsCategories;

const filteredLabels = labels.reduce((acc: any, val: ProcessLabel) => {
const { category } = val;
if (!acc[category]) {
acc[category] = [];
}
acc[category].push(val);
return acc;
}, {});

const categorizedLabels = {
[l1LevelOrganisation]: filteredLabels[l1LevelOrganisation] || [],
[functionalArea]: filteredLabels[functionalArea] || [],
[assets]: filteredLabels[assets] || [],
};

const noOfLabels =
categorizedLabels[l1LevelOrganisation].length +
categorizedLabels[functionalArea].length +
categorizedLabels[assets].length;

return [categorizedLabels, noOfLabels];
}
27 changes: 27 additions & 0 deletions utils/toggleLabels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Returns updated empty array / single label ID / array of label IDs
* @param selectedLabelId : labelID of the label to add / remove if already contained in current array of label IDs
* @param activeLabelIdArray : current array of labels / undefined if no label has been added yet
* @param isSelect : boolean value either to add / remove from the current array
* @returns : Returns updated empty array / single label ID / array of label IDs
*/

export function toggleLabels(
selectedLabelId: string,
activeLabelIdArray: undefined | string | string[],
isSelect: boolean
): string | string[] {
if (activeLabelIdArray) {
const labelArray = `${activeLabelIdArray}`.split(",");
const index = labelArray.findIndex((element) => element == selectedLabelId);
if (index == -1 && isSelect) {
labelArray.push(selectedLabelId);
return labelArray;
}
if (index !== -1 && !isSelect) {
labelArray.splice(index, 1);
return labelArray;
}
}
return selectedLabelId;
}
Loading