Skip to content

Commit 7c6c34f

Browse files
author
Victoria Ivanova
committed
fix endless skeleton for new report; add button spinners
1 parent 1edbbfc commit 7c6c34f

File tree

7 files changed

+67
-52
lines changed

7 files changed

+67
-52
lines changed

frontend/src/components/SaveButton/SaveButton.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,25 @@ import React from "react";
33
interface SaveButtonProps {
44
isChanged: boolean;
55
onSave: () => void;
6+
isLoading: boolean;
67
}
78

8-
const SaveButton: React.FC<SaveButtonProps> = ({ isChanged, onSave }) => {
9+
const SaveButton: React.FC<SaveButtonProps> = ({
10+
isChanged,
11+
onSave,
12+
isLoading,
13+
}) => {
914
return (
1015
<button
1116
onClick={onSave}
1217
className={`btn btn-info px-4 py-2`}
1318
disabled={!isChanged}
1419
>
15-
Сохранить
20+
{isLoading ? (
21+
<span className="loading loading-spinner"></span>
22+
) : (
23+
"Сохранить"
24+
)}
1625
</button>
1726
);
1827
};

frontend/src/pages/Report/Report.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,13 @@ const ReportPage = () => {
9191

9292
return (
9393
<div className="reports-wrapper">
94-
<ReportHeader />
94+
<ReportHeader isNewReport={isNewReport} />
9595
{bugsIds.length ? (
9696
bugsIds.map((id) => (
97-
<Bug key={id} reportId={reportForm.id} bugId={id} />
97+
<Bug key={id} bugId={id} reportId={reportForm.id} />
9898
))
9999
) : (
100-
<Bug />
100+
<Bug isNewReport />
101101
)}
102102

103103
{!isNewReport && bugsIds.length > 0 && !isExists && (

frontend/src/pages/Report/components/Bug/Bug.tsx

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,44 @@ import {
99
updateBugEvent,
1010
resetBug,
1111
updateBugApiEvent,
12+
$bugRequestState,
1213
} from "@/store/bugs";
1314
import { $reportRequestState } from "@/store/report";
1415
import { $attachmentsByBugId } from "@/store/attachments";
1516
import "./Bug.css";
1617
import CancelButton from "@/components/CancelButton/CancelButton";
1718
import SaveButton from "@/components/SaveButton/SaveButton";
1819
import Dropdown from "@/components/Dropdown/Dropdown";
19-
import { BugStatuses } from "@/const";
20+
import { BugStatuses, RequestStates } from "@/const";
2021
import Chat from "./components/Chat/Chat";
2122
import { uploadAttachmentFx } from "@/store/attachments";
2223
import { Bug as BugType } from "@/types/bug";
2324
import Result from "./components/Result/Result";
2425
import { ChangeEvent } from "react";
2526
import Heading from "./components/Heading/Heading";
26-
import { RequestStates } from "../../../../const/index";
2727

2828
type BugProps = {
2929
reportId?: number | null;
30+
isNewReport?: boolean;
3031
bugId?: number;
3132
};
3233

33-
const Bug = ({ reportId, bugId }: BugProps) => {
34-
const [updateBugData, reset, updateBugApi, createBugApi, uploadAttachment] =
35-
useUnit([
36-
updateBugEvent,
37-
resetBug,
38-
updateBugApiEvent,
39-
createBugEventByApi,
40-
uploadAttachmentFx,
41-
]);
34+
const Bug = ({ reportId, isNewReport, bugId }: BugProps) => {
35+
const [
36+
updateBugData,
37+
reset,
38+
updateBugApi,
39+
createBugApi,
40+
uploadAttachment,
41+
bugRequestState,
42+
] = useUnit([
43+
updateBugEvent,
44+
resetBug,
45+
updateBugApiEvent,
46+
createBugEventByApi,
47+
uploadAttachmentFx,
48+
$bugRequestState,
49+
]);
4250

4351
const [newBugData, updateNewBugData] = useUnit([$newBugStore, updateNewBug]);
4452

@@ -72,7 +80,6 @@ const Bug = ({ reportId, bugId }: BugProps) => {
7280
});
7381

7482
const isNewBug = !bug.id;
75-
const isNewReport = !reportId;
7683

7784
const isBugChanged = isNewBug
7885
? newBugData.receive !== "" && newBugData.expect !== ""
@@ -145,7 +152,7 @@ const Bug = ({ reportId, bugId }: BugProps) => {
145152
)}
146153

147154
{/* Селект статуса (только для существующего бага) */}
148-
{!isNewBug && reportRequestState !== RequestStates.PENDING && (
155+
{!isNewBug && reportRequestState === RequestStates.DONE && (
149156
<Dropdown
150157
className="max-w-[150px]"
151158
onChange={(selected) => {
@@ -197,7 +204,11 @@ const Bug = ({ reportId, bugId }: BugProps) => {
197204
}
198205
}}
199206
/>
200-
<SaveButton isChanged={isBugChanged} onSave={handleSave} />
207+
<SaveButton
208+
isChanged={isBugChanged}
209+
onSave={handleSave}
210+
isLoading={bugRequestState === RequestStates.PENDING}
211+
/>
201212
</div>
202213
)}
203214
{!isNewBug && (

frontend/src/pages/Report/components/Bug/components/Heading/Heading.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ type Props = {
44
};
55

66
const Heading = ({ isNewBug, bugId }: Props) => {
7-
return isNewBug ? (
8-
<span className="text-2xl">Новый баг</span>
9-
) : (
7+
return (
108
<span className="text-2xl">
11-
Баг<span className="text-gray-300">#{bugId}</span>
9+
{!isNewBug ? (
10+
<>
11+
Баг <span className="text-gray-300">#{bugId}</span>
12+
</>
13+
) : (
14+
"Новый баг"
15+
)}
1216
</span>
1317
);
1418
};

frontend/src/pages/Report/components/ReportHeader/ReportHeader.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
updateResponsible,
66
resetReport,
77
$isReportChanged,
8-
$isNewReport,
98
$reportRequestState,
109
updateStatus,
1110
updateReportEvent,
@@ -29,15 +28,14 @@ const autocompleteUsers = async (searchString: string) => {
2928
}));
3029
};
3130

32-
const ReportHeader = () => {
31+
const ReportHeader = ({ isNewReport }: { isNewReport: boolean }) => {
3332
const [
3433
reportForm,
3534
setTitle,
3635
setResponsibleId,
3736
isReportChanged,
3837
reportRequestState,
3938
reset,
40-
isNewReport,
4139
setUpdateStatus,
4240
updateReport,
4341
] = useUnit([
@@ -47,7 +45,6 @@ const ReportHeader = () => {
4745
$isReportChanged,
4846
$reportRequestState,
4947
resetReport,
50-
$isNewReport,
5148
updateStatus,
5249
updateReportEvent,
5350
]);
@@ -66,7 +63,7 @@ const ReportHeader = () => {
6663
}`}
6764
>
6865
<div className="flex justify-between items-center">
69-
{reportRequestState !== RequestStates.DONE ? (
66+
{reportRequestState !== RequestStates.DONE && !isNewReport ? (
7067
<div className="skeleton min-h-[40px]" />
7168
) : (
7269
<span className="text-2xl">
@@ -97,7 +94,7 @@ const ReportHeader = () => {
9794
</div>
9895
<div>
9996
<div className="text-xs font-semibold mt-1 mb-1">Заголовок</div>
100-
{reportRequestState !== RequestStates.DONE ? (
97+
{reportRequestState !== RequestStates.DONE && !isNewReport ? (
10198
<div className="skeleton input w-full" />
10299
) : (
103100
<input
@@ -115,7 +112,7 @@ const ReportHeader = () => {
115112
<div>
116113
<div className="text-xs font-semibold mb-1">Ответственный</div>
117114
<div className="flex gap-4 items-center">
118-
{reportRequestState !== RequestStates.DONE ? (
115+
{reportRequestState !== RequestStates.DONE && !isNewReport ? (
119116
<div className="skeleton input shrink-0 min-w-[288px]" />
120117
) : (
121118
<Autosuggest
@@ -129,7 +126,7 @@ const ReportHeader = () => {
129126
/>
130127
)}
131128
<div className="participants-wrapper">
132-
{reportRequestState !== RequestStates.DONE ? (
129+
{reportRequestState !== RequestStates.DONE && !isNewReport ? (
133130
<ParticipantsSkeleton />
134131
) : (
135132
!!reportForm.participants?.length &&
@@ -146,7 +143,11 @@ const ReportHeader = () => {
146143
{!isNewReport && isReportChanged && reportForm.responsible?.id && (
147144
<div className="flex gap-2 justify-end">
148145
<CancelButton isChanged={isReportChanged} onReset={reset} />
149-
<SaveButton isChanged={isReportChanged} onSave={updateReport} />
146+
<SaveButton
147+
isLoading={reportRequestState === RequestStates.PENDING}
148+
isChanged={isReportChanged}
149+
onSave={updateReport}
150+
/>
150151
</div>
151152
)}
152153
</div>

frontend/src/store/bugs.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { createBugFx } from "./newBug";
33
import { $initialReportForm, clearReport } from "./report";
44
import { updateBugApi } from "@/api/reports/bug";
55
import { Bug, UpdateBugParameters } from "@/types/bug";
6+
import { RequestStates } from "@/const";
67

78
type UpdateBugParams = {
89
reportId: number;
@@ -101,6 +102,15 @@ export const $bugsIds = createStore<number[]>([])
101102
)
102103
.reset(clearReport);
103104

105+
export const $bugRequestState = createStore(RequestStates.IDLE);
106+
$bugRequestState
107+
.on(updateBugFx.pending, (_, state) => {
108+
return state ? RequestStates.PENDING : RequestStates.DONE;
109+
})
110+
.on(updateBugFx.doneData, () => {
111+
return RequestStates.DONE;
112+
});
113+
104114
sample({
105115
source: updateBugApiEvent,
106116
fn: (bug) => ({

frontend/src/store/report.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,6 @@ export const updateTitle = createEvent<string>();
8585
export const updateStatus = createEvent<number>();
8686
export const updateResponsible = createEvent<User | null>();
8787

88-
export const setIsNewReport = createEvent();
89-
90-
export const $isNewReport = createStore(true)
91-
.on(setIsNewReport, (_, isNew) => isNew)
92-
.reset(clearReport);
93-
9488
export const $reportRequestState = createStore(RequestStates.IDLE);
9589
$reportRequestState
9690
.on(fetchReportFx.pending, (_, state) => {
@@ -150,20 +144,6 @@ sample({
150144
target: $reportForm, // Копируем данные в редактируемый стор
151145
});
152146

153-
// При загрузке отчёта устанавливаем `isNewReport`
154-
sample({
155-
source: fetchReportFx.doneData,
156-
fn: () => false, // Если отчёт загружен, это НЕ новый отчёт
157-
target: setIsNewReport,
158-
});
159-
160-
// При создании отчёта обновляем `isNewReport`
161-
sample({
162-
source: createReportFx.doneData,
163-
fn: () => false, // После успешного создания отчёта считаем его существующим
164-
target: setIsNewReport,
165-
});
166-
167147
sample({
168148
source: $combinedForm, // { reportForm, initialForm }
169149
clock: updateReportEvent,

0 commit comments

Comments
 (0)