Skip to content

Commit 48116e1

Browse files
vikaivVictoria Ivanova
andauthored
New layout: bugs (#39)
* add typography plugin for tilwind; update start script and gitignore * draft new layout * fetch users from /v1/users/batch/list; styles for satus select * refactor app for organizing old and new layout; styles for sidebar * clean up * add layout and actions for existing bugs * remove useBugActions hook; move all actions to bugs store; update bug data by socket; change expected/received bug title icons * useStoreMap for render list of bugs * move store relations to store/index.ts * remove changeBugStatus event, use updateBugDataEvent for status --------- Co-authored-by: Victoria Ivanova <victoria.i@ati.su>
1 parent 7f6c902 commit 48116e1

File tree

21 files changed

+768
-146
lines changed

21 files changed

+768
-146
lines changed

frontend/src/components/Layout/Layout.css

Lines changed: 0 additions & 4 deletions
This file was deleted.

frontend/src/components/Layout/Layout.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import React from "react";
22
import Header from "../Header/Header";
33

4-
import "./Layout.css";
54
import Sidebar from "../Sidebar/Sidebar";
65

76
const Layout = ({ children }: { children: React.ReactNode }) => {
87
return (
98
<div className="flex flex-col h-full">
109
<Header />
11-
<div className="grid grid-cols-[1fr_300px] grow">
12-
<div className="flex flex-col gap-4 px-6 py-8">{children}</div>
10+
<div className="grid grid-cols-[minmax(0,1fr)_300px] grow">
11+
<main className="flex flex-col gap-4 px-6 py-8 max-w-[1024px] mx-auto w-full">
12+
{children}
13+
</main>
1314
<Sidebar />
1415
</div>
1516
</div>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
main {
1+
.main-obsolete {
22
max-width: 1440px;
33
margin: 0 auto 60px;
44
}
55

66
@media (max-width: 1460px) {
7-
main {
7+
.main-obsolete {
88
margin: 0 10px 60px;
99
}
1010
}

frontend/src/components/LayoutObsolette/Layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const Layout = ({ children }: { children: React.ReactNode }) => {
2626
<input id="my-drawer" type="checkbox" className="drawer-toggle" />
2727
<div className="drawer-content">
2828
<Header />
29-
<main className="flex flex-col gap-4">
29+
<main className="flex flex-col gap-4 main-obsolete">
3030
<Breadcrumbs breadcrumbs={breadcrumbs} />
3131
{children}
3232
</main>

frontend/src/components/Sidebar/Sidebar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
$participantsWithNamesStore,
99
changeResponsibleUserIdEvent,
1010
} from "@/store/report";
11-
import StatusSelect from "./components/StatusSelect";
11+
import ReportStatusSelect from "./components/ReportStatusSelect";
1212

1313
const autocompleteUsersHandler = async (searchString: string) => {
1414
const response = await autocompleteUsers(searchString);
@@ -26,7 +26,7 @@ const Sidebar = () => {
2626
<div className="flex flex-col gap-4 px-6 py-8 border-l border-base-content/30 rounded-l-sm">
2727
<div className="flex flex-col gap-2">
2828
<div className="text-sm text-base-content/70">Статус</div>
29-
<StatusSelect />
29+
<ReportStatusSelect />
3030
</div>
3131

3232
<div className="flex flex-col gap-2">
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { useUnit } from "effector-react";
2+
import { ReportStatuses } from "@/const";
3+
import { $statusStore, changeStatusEvent } from "@/store/report";
4+
import StatusIndicator, {
5+
StatusConfig,
6+
} from "@/components/StatusIndicator/StatusIndicator";
7+
import StatusSelect from "@/components/StatusSelect/StatusSelect";
8+
import { CircleCheck, Clock, XCircle } from "lucide-react";
9+
import { CircleDashed } from "lucide-react";
10+
11+
const reportStatusConfig: StatusConfig<ReportStatuses> = {
12+
[ReportStatuses.BACKLOG]: {
13+
label: "Бэклог",
14+
icon: CircleDashed,
15+
iconColor: "text-base-content",
16+
},
17+
[ReportStatuses.IN_PROGRESS]: {
18+
label: "В работе",
19+
icon: Clock,
20+
iconColor: "text-warning",
21+
},
22+
[ReportStatuses.RESOLVED]: {
23+
label: "Готово",
24+
icon: CircleCheck,
25+
iconColor: "text-success",
26+
},
27+
[ReportStatuses.REJECTED]: {
28+
label: "Отменён",
29+
icon: XCircle,
30+
iconColor: "text-error",
31+
},
32+
};
33+
34+
const reportStatusOptions = [
35+
{
36+
value: ReportStatuses.BACKLOG,
37+
indicator: (
38+
<StatusIndicator
39+
status={ReportStatuses.BACKLOG}
40+
config={reportStatusConfig}
41+
/>
42+
),
43+
},
44+
{
45+
value: ReportStatuses.IN_PROGRESS,
46+
indicator: (
47+
<StatusIndicator
48+
status={ReportStatuses.IN_PROGRESS}
49+
config={reportStatusConfig}
50+
/>
51+
),
52+
},
53+
{
54+
value: ReportStatuses.RESOLVED,
55+
indicator: (
56+
<StatusIndicator
57+
status={ReportStatuses.RESOLVED}
58+
config={reportStatusConfig}
59+
/>
60+
),
61+
},
62+
{
63+
value: ReportStatuses.REJECTED,
64+
indicator: (
65+
<StatusIndicator
66+
status={ReportStatuses.REJECTED}
67+
config={reportStatusConfig}
68+
/>
69+
),
70+
},
71+
];
72+
73+
const ReportStatusSelect = () => {
74+
const status = useUnit($statusStore);
75+
76+
return (
77+
<StatusSelect
78+
status={status}
79+
options={reportStatusOptions}
80+
onChange={changeStatusEvent}
81+
className="w-full"
82+
/>
83+
);
84+
};
85+
86+
export default ReportStatusSelect;

frontend/src/components/Sidebar/components/StatusIndicator.tsx

Lines changed: 0 additions & 49 deletions
This file was deleted.

frontend/src/components/Sidebar/components/StatusSelect.tsx

Lines changed: 0 additions & 40 deletions
This file was deleted.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { ReactElement } from "react";
2+
3+
export type StatusConfig<T extends string | number | symbol> = Record<
4+
T,
5+
{
6+
label: string;
7+
icon: React.ElementType;
8+
iconColor: string;
9+
}
10+
>;
11+
12+
type Props<T extends string | number | symbol> = {
13+
status: T;
14+
config: StatusConfig<T>;
15+
};
16+
17+
const StatusIndicator = <T extends string | number | symbol>({
18+
status,
19+
config,
20+
}: Props<T>): ReactElement => {
21+
const statusInfo = config[status];
22+
23+
if (!statusInfo) {
24+
return (
25+
<div className="flex items-center space-x-2">
26+
<span className="text-sm text-base-content/50">Неизвестный статус</span>
27+
</div>
28+
);
29+
}
30+
31+
const { label, icon: Icon, iconColor } = statusInfo;
32+
33+
return (
34+
<div className="flex items-center space-x-2">
35+
<Icon className={`w-4 h-4 ${iconColor}`} />
36+
<span className="text-sm">{label}</span>
37+
</div>
38+
);
39+
};
40+
41+
export default StatusIndicator;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { ReactNode } from "react";
2+
3+
export type StatusOption<T> = {
4+
value: T;
5+
indicator: ReactNode;
6+
};
7+
8+
type Props<T> = {
9+
status: T;
10+
options: StatusOption<T>[];
11+
onChange: (status: T) => void;
12+
className?: string;
13+
};
14+
15+
const StatusSelect = <T,>({
16+
status,
17+
options,
18+
onChange,
19+
className = "",
20+
}: Props<T>) => {
21+
const currentOption = options.find((option) => option.value === status);
22+
23+
return (
24+
<div className={`dropdown dropdown-end ${className}`}>
25+
<label
26+
tabIndex={0}
27+
className="flex items-center gap-2 justify-start cursor-pointer hover:bg-base-200 p-2 rounded"
28+
>
29+
{currentOption?.indicator}
30+
</label>
31+
32+
<ul
33+
tabIndex={0}
34+
className="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-48 mt-1 z-10"
35+
>
36+
{options.map((option) => (
37+
<li key={String(option.value)} onClick={() => onChange(option.value)}>
38+
<a className="flex items-center gap-2">{option.indicator}</a>
39+
</li>
40+
))}
41+
</ul>
42+
</div>
43+
);
44+
};
45+
46+
export default StatusSelect;

0 commit comments

Comments
 (0)