Skip to content

Commit

Permalink
feat: remise des icones de status et ajout de l'index de question (#1021
Browse files Browse the repository at this point in the history
)

* feat: remise des icones de status et ajout de l'index de question

* fix: hasura perm

* fix: css dark mode bugs

* fix: update url search with query

* Update targets/frontend/src/components/contributions/questionList/QuestionRow.tsx

Co-authored-by: Martial Maillot <[email protected]>

* fix(ui): breadcrumb style + menu collapse (#1022)

* fix: test

---------

Co-authored-by: Victor Zeinstra <[email protected]>
Co-authored-by: Caroline <[email protected]>
Co-authored-by: Martial Maillot <[email protected]>
  • Loading branch information
4 people authored Sep 25, 2023
1 parent 530043d commit d734c39
Show file tree
Hide file tree
Showing 32 changed files with 473 additions and 394 deletions.
25 changes: 25 additions & 0 deletions targets/frontend/__mocks__/@codegouvfr/react-dsfr/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const DEFAULT_VARIANTS = {
default: {
error: {},
info: {},
warning: {},
success: {},
grey: {},
},
};
module.exports = {
fr: {
colors: {
decisions: {
text: {
...DEFAULT_VARIANTS,
actionHigh: { blueCumulus: {} },
label: { greenBourgeon: {} },
},
background: {
...DEFAULT_VARIANTS,
},
},
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
useIsDark: jest.fn().mockReturnValue(false),
};
17 changes: 17 additions & 0 deletions targets/frontend/__mocks__/next/router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const route = jest.fn();
const router = {
asPath: "mock",
pathname: "mock",
push: jest.fn((path) => {
route(path);
return Promise.resolve();
}),
query: { q: "" },
route,
};

module.exports = {
...jest.requireActual("next/router"),

useRouter: () => router,
};
1 change: 0 additions & 1 deletion targets/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@
"sentry-testkit": "^3.3.4",
"serialize-error": "^9.1.1",
"strip-markdown": "^4.2.0",
"styled-components": "^5.3.9",
"swr": "^1.0.1",
"unified": "^9.2.2",
"unist-util-parents": "^1.0.3",
Expand Down
14 changes: 0 additions & 14 deletions targets/frontend/src/__tests__/contenus/contentList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,6 @@ import { render, RenderResult } from "@testing-library/react";
import { act } from "react-dom/test-utils";
import { DocumentsPage } from "src/pages/contenus";

jest.mock("next/router", () => ({
...jest.requireActual("next/router"),
useRouter: () => ({
query: {},
}),
}));

jest.mock("@codegouvfr/react-dsfr/useIsDark", () => ({
useIsDark: jest.fn().mockReturnValue(false),
}));
jest.mock("@codegouvfr/react-dsfr", () => ({
fr: jest.fn(),
}));

describe("Given parameters", () => {
describe("When rendering the component DocumentsPage", () => {
let rendering: RenderResult;
Expand Down
61 changes: 25 additions & 36 deletions targets/frontend/src/components/contributions/answers/Answer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,16 @@ import {
Box,
Button,
FormControl,
Grid,
Stack,
Typography,
} from "@mui/material";
import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { useUser } from "src/hooks/useUser";

import { FormEditionField, FormRadioGroup, FormTextField } from "../../forms";
import { StatusContainer } from "../status";
import {
Answer,
CdtnReference,
KaliReference,
LegiReference,
OtherReference,
Status,
} from "../type";
import { Answer, Status } from "../type";
import { useContributionAnswerUpdateMutation } from "./answer.mutation";
import { useContributionAnswerQuery } from "./answer.query";
import { Comments } from "./Comments";
Expand All @@ -32,21 +25,12 @@ import {
import { statusesMapping } from "../status/data";
import { getNextStatus, getPrimaryButtonLabel } from "../status/utils";
import { SnackBar } from "../../utils/SnackBar";
import { BreadcrumbLink } from "src/components/utils";
import { Breadcrumb, BreadcrumbLink } from "src/components/utils";

export type ContributionsAnswerProps = {
id: string;
};

export type AnswerForm = {
otherAnswer?: string;
content?: string;
kaliReferences: KaliReference[];
legiReferences: LegiReference[];
otherReferences: OtherReference[];
cdtnReferences: CdtnReference[];
};

const isNotEditable = (answer: Answer | undefined) =>
answer?.status.status !== "REDACTING" &&
answer?.status.status !== "TODO" &&
Expand Down Expand Up @@ -147,27 +131,32 @@ export const ContributionsAnswer = ({
];
return (
<>
<Grid container>
<Grid xs={10}>
<ol aria-label="breadcrumb" className="fr-breadcrumb__list">
<BreadcrumbLink href={"/contributions"}>
Contributions
</BreadcrumbLink>
<BreadcrumbLink
href={`/contributions/questions/${answer?.question.id}`}
>
<Stack direction="row" justifyContent="space-between">
<Breadcrumb>
<BreadcrumbLink
href={`/contributions/questions/${answer?.question.id}`}
>
<>
<Typography
sx={{
display: "inline-block",
fontSize: "1.4rem",
fontWeight: "bold",
}}
>
[{answer?.question?.order}]
</Typography>{" "}
{answer?.question?.content}
</BreadcrumbLink>
<BreadcrumbLink>{answer?.agreement?.id}</BreadcrumbLink>
</ol>
</Grid>
</>
</BreadcrumbLink>
<BreadcrumbLink>{answer?.agreement?.id}</BreadcrumbLink>
</Breadcrumb>
{answer?.status && (
<Grid xs={2} style={{ color: statusesMapping[status].color }}>
<div style={{ color: statusesMapping[status].color }}>
<StatusContainer status={answer.status} />
</Grid>
</div>
)}
</Grid>
<h2>{answer?.agreement?.name}</h2>
</Stack>
<Box sx={{ display: "flex", flexDirection: "row" }}>
<Box sx={{ width: "70%" }}>
<form
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ query contribution_answer($id: uuid) {
question {
id
content
order
}
agreement {
id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ type QueryResult = {
export const useContributionSearchCdtnReferencesQuery = (
query: string | undefined
): Result<Pick<CdtnReference, "document">> => {
const [slug] = query?.split("/").reverse() ?? [""];
const hrefWithoutQuery: string | undefined = query?.split("?")[0];
const [slug] = hrefWithoutQuery?.split("/").reverse() ?? [""];
const title = `%${slug
?.split(/[\ \-\,]/gm)
?.map((text) => text.normalize().replace(/[\u0300-\u036f]/g, ""))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ export const questionListQuery = `query questions_answers($search: String) {
contribution_questions(
where: {
content: { _ilike: $search }
}
},
order_by: {order: asc}
) {
id,
content,
order,
answers {
statuses(order_by: {created_at: desc}, limit: 1) {
status
Expand All @@ -22,7 +24,7 @@ export const questionListQuery = `query questions_answers($search: String) {
}
}`;
export type QueryQuestionAnswer = Pick<Answer, "status">;
export type QueryQuestion = Pick<Question, "id" | "content"> & {
export type QueryQuestion = Pick<Question, "id" | "content" | "order"> & {
answers: QueryQuestionAnswer[];
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,29 @@ import {
TableHead,
TableRow,
TextField,
Tooltip,
Typography,
} from "@mui/material";
import { useState } from "react";

import { useQuestionListQuery } from "./QuestionList.query";
import { countAnswersWithStatus, QuestionRow } from "./QuestionRow";
import {
QueryQuestionAnswer,
useQuestionListQuery,
} from "./QuestionList.query";
import { QuestionRow } from "./QuestionRow";
import { fr } from "@codegouvfr/react-dsfr";
import { statusesMapping } from "../status/data";
import { StatusStats } from "../status/StatusStats";

export function getPercentage(count: number, total: number) {
return ((count / total) * 100).toFixed(2);
}
export const countAnswersWithStatus = (
answers: QueryQuestionAnswer[] | undefined,
statusToCount: string
): number => {
const count = answers?.filter((answer) => {
return answer.status?.status === statusToCount;
}).length;
return count ?? 0;
};

export const QuestionList = (): JSX.Element => {
const [search, setSearch] = useState<string | undefined>();
Expand All @@ -33,7 +44,13 @@ export const QuestionList = (): JSX.Element => {
const total = aggregatedRow.length;
return (
<Stack spacing={2}>
<Stack direction="row" alignItems="start" spacing={2}>
<Stack
direction="row"
alignItems="center"
spacing={1}
useFlexGap
flexWrap="wrap"
>
<TextField
label="Recherche"
variant="outlined"
Expand All @@ -50,40 +67,36 @@ export const QuestionList = (): JSX.Element => {
sx={{
fontWeight: "bold",
color: fr.colors.decisions.text.default.grey.default,
marginBottom: "24px",
}}
>
{total}
</Typography>
</CardContent>
</Card>

{Object.entries(statusesMapping).map(([status, { text, color }]) => {
const count = countAnswersWithStatus(aggregatedRow, status);
return (
<Card key={status}>
<CardContent sx={{ color }}>
{text}
<Typography sx={{ fontWeight: "bold" }}>{count}</Typography>
<span>{getPercentage(count, total)}%</span>
</CardContent>
</Card>
);
})}
<StatusStats
statusCounts={Object.keys(statusesMapping).map((status) => ({
status,
count: countAnswersWithStatus(aggregatedRow, status),
}))}
total={total}
></StatusStats>
</Stack>

<TableContainer component={Paper}>
<Table aria-label="collapsible table" size="small">
<TableHead>
<TableRow>
<TableCell>Questions ({rows.length})</TableCell>
{Object.entries(statusesMapping).map(([_, { text, color }]) => {
return (
<TableCell key={text} style={{ color }} align="center">
{text}
</TableCell>
);
})}
{Object.entries(statusesMapping).map(
([_, { text, icon, color }]) => {
return (
<TableCell key={text} style={{ color }} align="center">
<Tooltip title={text}>{icon}</Tooltip>
</TableCell>
);
}
)}
</TableRow>
</TableHead>
<TableBody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@ import TableRow from "@mui/material/TableRow";
import { useRouter } from "next/router";

import { StatusRecap } from "../status";
import { QueryQuestion, QueryQuestionAnswer } from "./QuestionList.query";

export const countAnswersWithStatus = (
answers: QueryQuestionAnswer[] | undefined,
statusToCount: string
): number =>
answers?.filter(({ status }) => status?.status === statusToCount).length ?? 0;
import { QueryQuestion } from "./QuestionList.query";

export const QuestionRow = (props: { row: QueryQuestion }) => {
const { row } = props;
Expand All @@ -26,9 +20,9 @@ export const QuestionRow = (props: { row: QueryQuestion }) => {
hover
>
<TableCell component="th" scope="row">
{row.content}
<strong>{row.order}</strong> - {row.content}
</TableCell>
<StatusRecap answers={row.answers} key={`${row.id}-statuses`} />
<StatusRecap answers={row.answers} uniqKey={`${row.id}-statuses`} />
</TableRow>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const mock: QuestionListQueryResult = {
],
content: "question1",
id: "questionId1",
order: 1,
},
{
answers: [
Expand All @@ -41,6 +42,7 @@ export const mock: QuestionListQueryResult = {
],
content: "question2",
id: "questionId2",
order: 2,
},
],
};
Expand Down
Loading

0 comments on commit d734c39

Please sign in to comment.