Skip to content

Commit ca12ffb

Browse files
committed
refactor: SingleProblemListのreact-refetch を置き換える
1 parent 22e7ca1 commit ca12ffb

File tree

3 files changed

+104
-82
lines changed

3 files changed

+104
-82
lines changed

atcoder-problems-frontend/src/pages/Internal/ApiUrl.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ export const LIST_UPDATE = `${BASE_URL}/list/update`;
1515
export const LIST_ITEM_UPDATE = `${BASE_URL}/list/item/update`;
1616
export const LIST_ITEM_DELETE = `${BASE_URL}/list/item/delete`;
1717
export const LIST_ITEM_ADD = `${BASE_URL}/list/item/add`;
18-
export const listGetUrl = (listId: string): string =>
19-
`${BASE_URL}/list/get/${listId}`;
2018

2119
export const PROGRESS_RESET_LIST = `${BASE_URL}/progress_reset/list`;
2220
export const PROGRESS_RESET_ADD = `${BASE_URL}/progress_reset/add`;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {
2+
LIST_ITEM_ADD,
3+
LIST_ITEM_DELETE,
4+
LIST_ITEM_UPDATE,
5+
LIST_UPDATE,
6+
} from "../ApiUrl";
7+
8+
export const updateProblemList = (name: string, listId: string) =>
9+
fetch(LIST_UPDATE, {
10+
method: "POST",
11+
headers: {
12+
"Content-Type": "application/json",
13+
},
14+
body: JSON.stringify({ internal_list_id: listId, name }),
15+
});
16+
17+
export const addProblemItem = (problemId: string, listId: string) =>
18+
fetch(LIST_ITEM_ADD, {
19+
method: "POST",
20+
headers: {
21+
"Content-Type": "application/json",
22+
},
23+
body: JSON.stringify({
24+
internal_list_id: listId,
25+
problem_id: problemId,
26+
}),
27+
});
28+
29+
export const deleteProblemItem = (problemId: string, listId: string) =>
30+
fetch(LIST_ITEM_DELETE, {
31+
method: "POST",
32+
headers: {
33+
"Content-Type": "application/json",
34+
},
35+
body: JSON.stringify({
36+
internal_list_id: listId,
37+
problem_id: problemId,
38+
}),
39+
});
40+
41+
export const updateProblemItem = (
42+
problemId: string,
43+
memo: string,
44+
listId: string
45+
) =>
46+
fetch(LIST_ITEM_UPDATE, {
47+
method: "POST",
48+
headers: {
49+
"Content-Type": "application/json",
50+
},
51+
body: JSON.stringify({
52+
internal_list_id: listId,
53+
problem_id: problemId,
54+
memo,
55+
}),
56+
});

atcoder-problems-frontend/src/pages/Internal/ProblemList/SingleProblemList.tsx

Lines changed: 48 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, { useState } from "react";
2-
import { connect, PromiseState } from "react-refetch";
32
import { List } from "immutable";
43
import {
54
Alert,
@@ -15,49 +14,57 @@ import {
1514
Spinner,
1615
} from "reactstrap";
1716
import { useProblems } from "../../../api/APIClient";
18-
import { useLoginState } from "../../../api/InternalAPIClient";
19-
import {
20-
LIST_ITEM_ADD,
21-
LIST_ITEM_DELETE,
22-
LIST_ITEM_UPDATE,
23-
LIST_UPDATE,
24-
listGetUrl,
25-
} from "../ApiUrl";
17+
import { useLoginState, useProblemList } from "../../../api/InternalAPIClient";
2618
import Problem from "../../../interfaces/Problem";
2719
import { ProblemSearchBox } from "../../../components/ProblemSearchBox";
2820
import { formatProblemUrl } from "../../../utils/Url";
29-
import { ProblemList, ProblemListItem } from "../types";
21+
import { ProblemListItem } from "../types";
3022
import { NewTabLink } from "../../../components/NewTabLink";
3123
import { ContestCreatePage } from "../VirtualContest/ContestCreatePage";
32-
33-
interface OuterProps {
24+
import {
25+
updateProblemList,
26+
addProblemItem,
27+
deleteProblemItem,
28+
updateProblemItem,
29+
} from "./ApiClient";
30+
interface Props {
3431
listId: string;
3532
}
36-
interface InnerProps extends OuterProps {
37-
problemListFetch: PromiseState<ProblemList>;
38-
updateList: (name: string) => void;
39-
updateListResponse: PromiseState<Record<string, unknown> | null>;
4033

41-
addItem: (problemId: string) => void;
42-
deleteItem: (problemId: string) => void;
43-
updateItem: (problemId: string, memo: string) => void;
44-
}
34+
const updateList = async (name: string, listId: string) => {
35+
await updateProblemList(name, listId);
36+
};
37+
38+
const addItem = async (problemId: string, listId: string) => {
39+
await addProblemItem(problemId, listId);
40+
};
41+
42+
const deleteItem = async (problemId: string, listId: string) => {
43+
await deleteProblemItem(problemId, listId);
44+
};
4545

46-
const InnerSingleProblemList = (props: InnerProps) => {
46+
const updateItem = async (problemId: string, memo: string, listId: string) => {
47+
await updateProblemItem(problemId, memo, listId);
48+
};
49+
50+
export const SingleProblemList = (props: Props) => {
51+
const { listId } = props;
4752
const loginState = useLoginState();
4853
const [adding, setAdding] = useState(false);
4954
const [creatingContest, setCreatingContest] = useState(false);
5055
const problems = useProblems() ?? [];
5156

52-
const { problemListFetch } = props;
57+
const problemListFetch = useProblemList(listId);
58+
5359
const internalUserId = loginState.data?.internal_user_id;
54-
if (problemListFetch.pending) {
60+
61+
if (!problemListFetch.data && !problemListFetch.error) {
5562
return <Spinner style={{ width: "3rem", height: "3rem" }} />;
56-
} else if (problemListFetch.rejected || !problemListFetch.value) {
63+
} else if (!problemListFetch.data) {
5764
return <Alert color="danger">Failed to fetch list info.</Alert>;
5865
}
59-
const listInfo = problemListFetch.value;
60-
const modifiable = listInfo.internal_user_id === internalUserId;
66+
const listInfo = problemListFetch.data;
67+
const modifiable = listInfo?.internal_user_id === internalUserId;
6168

6269
return creatingContest ? (
6370
<>
@@ -87,7 +94,7 @@ const InnerSingleProblemList = (props: InnerProps) => {
8794
<h2>
8895
<DoubleClickEdit
8996
modifiable={modifiable}
90-
saveText={(name): void => props.updateList(name)}
97+
saveText={(name) => updateList(name, listId)}
9198
initialText={listInfo.internal_list_name}
9299
/>
93100
</h2>
@@ -98,9 +105,11 @@ const InnerSingleProblemList = (props: InnerProps) => {
98105
{adding ? (
99106
<ProblemSearchBox
100107
problems={problems}
101-
selectProblem={(problem): void => {
102-
props.addItem(problem.id);
103-
}}
108+
selectProblem={(problem) =>
109+
addItem(problem.id, listId).then(() =>
110+
problemListFetch.mutate()
111+
)
112+
}
104113
/>
105114
) : modifiable ? (
106115
<Button color="success" onClick={(): void => setAdding(!adding)}>
@@ -130,10 +139,16 @@ const InnerSingleProblemList = (props: InnerProps) => {
130139
key={item.problem_id}
131140
item={item}
132141
problem={problem}
133-
saveText={(memo: string): void =>
134-
props.updateItem(item.problem_id, memo)
142+
saveText={(memo: string) =>
143+
updateItem(item.problem_id, memo, listId).then(() =>
144+
problemListFetch.mutate()
145+
)
146+
}
147+
deleteItem={() =>
148+
deleteItem(item.problem_id, listId).then(() =>
149+
problemListFetch.mutate()
150+
)
135151
}
136-
deleteItem={(): void => props.deleteItem(item.problem_id)}
137152
/>
138153
);
139154
})}
@@ -144,53 +159,6 @@ const InnerSingleProblemList = (props: InnerProps) => {
144159
);
145160
};
146161

147-
export const SingleProblemList = connect<OuterProps, InnerProps>((props) => ({
148-
problemListFetch: listGetUrl(props.listId),
149-
updateList: (name: string) => ({
150-
updateListResponse: {
151-
url: LIST_UPDATE,
152-
method: "POST",
153-
body: JSON.stringify({ internal_list_id: props.listId, name }),
154-
force: true,
155-
},
156-
}),
157-
updateListResponse: { value: null },
158-
addItem: (problemId: string) => ({
159-
problemListFetch: {
160-
url: LIST_ITEM_ADD,
161-
method: "POST",
162-
body: JSON.stringify({
163-
internal_list_id: props.listId,
164-
problem_id: problemId,
165-
}),
166-
then: (): string => listGetUrl(props.listId),
167-
},
168-
}),
169-
deleteItem: (problemId: string) => ({
170-
problemListFetch: {
171-
url: LIST_ITEM_DELETE,
172-
method: "POST",
173-
body: JSON.stringify({
174-
internal_list_id: props.listId,
175-
problem_id: problemId,
176-
}),
177-
then: (): string => listGetUrl(props.listId),
178-
},
179-
}),
180-
updateItem: (problemId: string, memo: string) => ({
181-
problemListFetch: {
182-
url: LIST_ITEM_UPDATE,
183-
method: "POST",
184-
body: JSON.stringify({
185-
internal_list_id: props.listId,
186-
problem_id: problemId,
187-
memo,
188-
}),
189-
then: (): string => listGetUrl(props.listId),
190-
},
191-
}),
192-
}))(InnerSingleProblemList);
193-
194162
const ProblemEntry: React.FC<{
195163
item: ProblemListItem;
196164
problem: Problem | undefined;

0 commit comments

Comments
 (0)