aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FrontEnd/src/views/admin/UserAdmin.tsx344
-rw-r--r--FrontEnd/src/views/center/index.tsx14
-rw-r--r--FrontEnd/src/views/common/dailog/ConfirmDialog.tsx2
-rw-r--r--FrontEnd/src/views/common/dailog/Dialog.css20
-rw-r--r--FrontEnd/src/views/common/dailog/Dialog.tsx51
-rw-r--r--FrontEnd/src/views/common/dailog/FullPageDialog.css4
-rw-r--r--FrontEnd/src/views/common/dailog/FullPageDialog.tsx8
-rw-r--r--FrontEnd/src/views/settings/index.tsx49
-rw-r--r--FrontEnd/src/views/timeline-common/MarkdownPostEdit.tsx16
-rw-r--r--FrontEnd/src/views/timeline-common/PostPropertyChangeDialog.tsx5
-rw-r--r--FrontEnd/src/views/timeline-common/TimelineMember.tsx2
-rw-r--r--FrontEnd/src/views/timeline-common/TimelinePageCardTemplate.tsx33
-rw-r--r--FrontEnd/src/views/timeline-common/TimelinePostView.tsx56
-rw-r--r--FrontEnd/src/views/timeline/TimelineCard.tsx16
14 files changed, 268 insertions, 352 deletions
diff --git a/FrontEnd/src/views/admin/UserAdmin.tsx b/FrontEnd/src/views/admin/UserAdmin.tsx
index f713b8b7..68d65409 100644
--- a/FrontEnd/src/views/admin/UserAdmin.tsx
+++ b/FrontEnd/src/views/admin/UserAdmin.tsx
@@ -6,29 +6,17 @@ import OperationDialog, {
} from "../common/dailog/OperationDialog";
import { AuthUser } from "@/services/user";
-import {
- getHttpUserClient,
- HttpUser,
- kUserPermissionList,
- UserPermission,
-} from "@/http/user";
+import { getHttpUserClient, HttpUser, kUserPermissionList } from "@/http/user";
import { Trans, useTranslation } from "react-i18next";
import Button from "../common/button/Button";
import Spinner from "../common/Spinner";
import FlatButton from "../common/button/FlatButton";
-interface DialogProps<TData = undefined, TReturn = undefined> {
+const CreateUserDialog: React.FC<{
open: boolean;
close: () => void;
- data: TData;
- onSuccess: (data: TReturn) => void;
-}
-
-const CreateUserDialog: React.FC<DialogProps<undefined, HttpUser>> = ({
- open,
- close,
- onSuccess,
-}) => {
+ onSuccess: (user: HttpUser) => void;
+}> = ({ open, close, onSuccess }) => {
return (
<OperationDialog
title="admin:user.dialog.create.title"
@@ -57,33 +45,35 @@ const UsernameLabel: React.FC = (props) => {
return <span style={{ color: "blue" }}>{props.children}</span>;
};
-const UserDeleteDialog: React.FC<DialogProps<{ username: string }, unknown>> =
- ({ open, close, data: { username }, onSuccess }) => {
- return (
- <OperationDialog
- open={open}
- onClose={close}
- title="admin:user.dialog.delete.title"
- themeColor="danger"
- inputPrompt={() => (
- <Trans i18nKey="admin:user.dialog.delete.prompt">
- 0<UsernameLabel>{username}</UsernameLabel>2
- </Trans>
- )}
- onProcess={() => getHttpUserClient().delete(username)}
- onSuccessAndClose={onSuccess}
- />
- );
- };
+const UserDeleteDialog: React.FC<{
+ open: boolean;
+ close: () => void;
+ user: HttpUser;
+ onSuccess: () => void;
+}> = ({ open, close, user, onSuccess }) => {
+ return (
+ <OperationDialog
+ open={open}
+ onClose={close}
+ title="admin:user.dialog.delete.title"
+ themeColor="danger"
+ inputPrompt={() => (
+ <Trans i18nKey="admin:user.dialog.delete.prompt">
+ 0<UsernameLabel>{user.username}</UsernameLabel>2
+ </Trans>
+ )}
+ onProcess={() => getHttpUserClient().delete(user.username)}
+ onSuccessAndClose={onSuccess}
+ />
+ );
+};
-const UserModifyDialog: React.FC<
- DialogProps<
- {
- oldUser: HttpUser;
- },
- HttpUser
- >
-> = ({ open, close, data: { oldUser }, onSuccess }) => {
+const UserModifyDialog: React.FC<{
+ open: boolean;
+ close: () => void;
+ user: HttpUser;
+ onSuccess: () => void;
+}> = ({ open, close, user, onSuccess }) => {
return (
<OperationDialog
open={open}
@@ -92,7 +82,7 @@ const UserModifyDialog: React.FC<
themeColor="danger"
inputPrompt={() => (
<Trans i18nKey="admin:user.dialog.modify.prompt">
- 0<UsernameLabel>{oldUser.username}</UsernameLabel>2
+ 0<UsernameLabel>{user.username}</UsernameLabel>2
</Trans>
)}
inputScheme={
@@ -100,21 +90,21 @@ const UserModifyDialog: React.FC<
{
type: "text",
label: "admin:user.username",
- initValue: oldUser.username,
+ initValue: user.username,
},
{ type: "text", label: "admin:user.password" },
{
type: "text",
label: "admin:user.nickname",
- initValue: oldUser.nickname,
+ initValue: user.nickname,
},
] as const
}
onProcess={([username, password, nickname]) =>
- getHttpUserClient().patch(oldUser.username, {
- username: username !== oldUser.username ? username : undefined,
+ getHttpUserClient().patch(user.username, {
+ username: username !== user.username ? username : undefined,
password: password !== "" ? password : undefined,
- nickname: nickname !== oldUser.nickname ? nickname : undefined,
+ nickname: nickname !== user.nickname ? nickname : undefined,
})
}
onSuccessAndClose={onSuccess}
@@ -122,17 +112,14 @@ const UserModifyDialog: React.FC<
);
};
-const UserPermissionModifyDialog: React.FC<
- DialogProps<
- {
- username: string;
- permissions: UserPermission[];
- },
- UserPermission[]
- >
-> = ({ open, close, data: { username, permissions }, onSuccess }) => {
+const UserPermissionModifyDialog: React.FC<{
+ open: boolean;
+ close: () => void;
+ user: HttpUser;
+ onSuccess: () => void;
+}> = ({ open, close, user, onSuccess }) => {
const oldPermissionBoolList: boolean[] = kUserPermissionList.map(
- (permission) => permissions.includes(permission)
+ (permission) => user.permissions.includes(permission)
);
return (
@@ -143,7 +130,7 @@ const UserPermissionModifyDialog: React.FC<
themeColor="danger"
inputPrompt={() => (
<Trans i18nKey="admin:user.dialog.modifyPermissions.prompt">
- 0<UsernameLabel>{username}</UsernameLabel>2
+ 0<UsernameLabel>{user.username}</UsernameLabel>2
</Trans>
)}
inputScheme={kUserPermissionList.map<OperationDialogBoolInput>(
@@ -160,90 +147,102 @@ const UserPermissionModifyDialog: React.FC<
const permission = kUserPermissionList[index];
if (oldValue === newValue) continue;
if (newValue) {
- await getHttpUserClient().putUserPermission(username, permission);
+ await getHttpUserClient().putUserPermission(
+ user.username,
+ permission
+ );
} else {
await getHttpUserClient().deleteUserPermission(
- username,
+ user.username,
permission
);
}
}
return newPermissionBoolList;
}}
- onSuccessAndClose={(newPermissionBoolList: boolean[]) => {
- const permissions: UserPermission[] = [];
- for (let index = 0; index < kUserPermissionList.length; index++) {
- if (newPermissionBoolList[index]) {
- permissions.push(kUserPermissionList[index]);
- }
- }
- onSuccess(permissions);
- }}
+ onSuccessAndClose={onSuccess}
/>
);
};
-const kModify = "modify";
-const kModifyPermission = "permission";
-const kDelete = "delete";
-
-type TModify = typeof kModify;
-type TModifyPermission = typeof kModifyPermission;
-type TDelete = typeof kDelete;
-
-type ContextMenuItem = TModify | TModifyPermission | TDelete;
-
interface UserItemProps {
- on: { [key in ContextMenuItem]: () => void };
user: HttpUser;
+ onChange: () => void;
}
-const UserItem: React.FC<UserItemProps> = ({ user, on }) => {
+const UserItem: React.FC<UserItemProps> = ({ user, onChange }) => {
const { t } = useTranslation();
+ const [dialog, setDialog] = useState<
+ "delete" | "modify" | "permission" | null
+ >(null);
+
const [editMaskVisible, setEditMaskVisible] = React.useState<boolean>(false);
return (
- <div className="admin-user-item">
- <i
- className="bi-pencil-square cru-float-right icon-button cru-color-primary-enhance"
- onClick={() => setEditMaskVisible(true)}
- />
- <h5 className="cru-color-primary">{user.username}</h5>
- <small className="d-block cru-color-secondary">
- {t("admin:user.nickname")}
- {user.nickname}
- </small>
- <small className="d-block cru-color-secondary">
- {t("admin:user.uniqueId")}
- {user.uniqueId}
- </small>
- <small className="d-block cru-color-secondary">
- {t("admin:user.permissions")}
- {user.permissions.map((permission) => {
- return (
- <span key={permission} className="cru-color-danger">
- {permission}{" "}
- </span>
- );
- })}
- </small>
- <div
- className={classnames("edit-mask", !editMaskVisible && "d-none")}
- onClick={() => setEditMaskVisible(false)}
- >
- <FlatButton text="admin:user.modify" onClick={on[kModify]} />
- <FlatButton
- text="admin:user.modifyPermissions"
- onClick={on[kModifyPermission]}
- />
- <FlatButton
- text="admin:user.delete"
- color="danger"
- onClick={on[kDelete]}
+ <>
+ <div className="admin-user-item">
+ <i
+ className="bi-pencil-square cru-float-right icon-button cru-color-primary-enhance"
+ onClick={() => setEditMaskVisible(true)}
/>
+ <h5 className="cru-color-primary">{user.username}</h5>
+ <small className="d-block cru-color-secondary">
+ {t("admin:user.nickname")}
+ {user.nickname}
+ </small>
+ <small className="d-block cru-color-secondary">
+ {t("admin:user.uniqueId")}
+ {user.uniqueId}
+ </small>
+ <small className="d-block cru-color-secondary">
+ {t("admin:user.permissions")}
+ {user.permissions.map((permission) => {
+ return (
+ <span key={permission} className="cru-color-danger">
+ {permission}{" "}
+ </span>
+ );
+ })}
+ </small>
+ <div
+ className={classnames("edit-mask", !editMaskVisible && "d-none")}
+ onClick={() => setEditMaskVisible(false)}
+ >
+ <FlatButton
+ text="admin:user.modify"
+ onClick={() => setDialog("modify")}
+ />
+ <FlatButton
+ text="admin:user.modifyPermissions"
+ onClick={() => setDialog("permission")}
+ />
+ <FlatButton
+ text="admin:user.delete"
+ color="danger"
+ onClick={() => setDialog("delete")}
+ />
+ </div>
</div>
- </div>
+ <UserDeleteDialog
+ open={dialog === "delete"}
+ close={() => setDialog(null)}
+ user={user}
+ onSuccess={onChange}
+ />
+ <UserModifyDialog
+ open={dialog === "modify"}
+ close={() => setDialog(null)}
+ user={user}
+ onSuccess={onChange}
+ />
+ <UserPermissionModifyDialog
+ open={dialog === "permission"}
+ close={() => setDialog(null)}
+ user={user}
+ onSuccess={onChange}
+ />
+ </>
);
};
@@ -252,24 +251,8 @@ interface UserAdminProps {
}
const UserAdmin: React.FC<UserAdminProps> = () => {
- type DialogInfo =
- | null
- | {
- type: "create";
- }
- | {
- type: TModify;
- user: HttpUser;
- }
- | {
- type: TModifyPermission;
- username: string;
- permissions: UserPermission[];
- }
- | { type: TDelete; username: string };
-
const [users, setUsers] = useState<HttpUser[] | null>(null);
- const [dialog, setDialog] = useState<DialogInfo>(null);
+ const [dialog, setDialog] = useState<"create" | null>(null);
const [usersVersion, setUsersVersion] = useState<number>(0);
const updateUsers = (): void => {
setUsersVersion(usersVersion + 1);
@@ -289,83 +272,10 @@ const UserAdmin: React.FC<UserAdminProps> = () => {
};
}, [usersVersion]);
- let dialogNode: React.ReactNode;
- if (dialog) {
- switch (dialog.type) {
- case "create":
- dialogNode = (
- <CreateUserDialog
- open
- close={() => setDialog(null)}
- data={undefined}
- onSuccess={updateUsers}
- />
- );
- break;
- case kDelete:
- dialogNode = (
- <UserDeleteDialog
- open
- close={() => setDialog(null)}
- data={{ username: dialog.username }}
- onSuccess={updateUsers}
- />
- );
- break;
- case kModify:
- dialogNode = (
- <UserModifyDialog
- open
- close={() => setDialog(null)}
- data={{ oldUser: dialog.user }}
- onSuccess={updateUsers}
- />
- );
- break;
- case kModifyPermission:
- dialogNode = (
- <UserPermissionModifyDialog
- open
- close={() => setDialog(null)}
- data={{
- username: dialog.username,
- permissions: dialog.permissions,
- }}
- onSuccess={updateUsers}
- />
- );
- break;
- }
- }
-
if (users) {
const userComponents = users.map((user) => {
return (
- <UserItem
- key={user.username}
- user={user}
- on={{
- modify: () => {
- setDialog({
- type: "modify",
- user,
- });
- },
- permission: () => {
- setDialog({
- type: kModifyPermission,
- username: user.username,
- permissions: user.permissions,
- });
- },
- delete: () => {
- setDialog({
- type: "delete",
- username: user.username,
- });
- },
- }}
- />
+ <UserItem key={user.username} user={user} onChange={updateUsers} />
);
});
@@ -376,16 +286,16 @@ const UserAdmin: React.FC<UserAdminProps> = () => {
<Button
text="admin:create"
color="success"
- onClick={() =>
- setDialog({
- type: "create",
- })
- }
+ onClick={() => setDialog("create")}
/>
</div>
</div>
{userComponents}
- {dialogNode}
+ <CreateUserDialog
+ open={dialog === "create"}
+ close={() => setDialog(null)}
+ onSuccess={updateUsers}
+ />
</>
);
} else {
diff --git a/FrontEnd/src/views/center/index.tsx b/FrontEnd/src/views/center/index.tsx
index d226e63c..430d9781 100644
--- a/FrontEnd/src/views/center/index.tsx
+++ b/FrontEnd/src/views/center/index.tsx
@@ -47,14 +47,12 @@ const HomePage: React.FC = () => {
</div>
<CenterBoards />
</div>
- {dialog === "create" && (
- <TimelineCreateDialog
- open
- close={() => {
- setDialog(null);
- }}
- />
- )}
+ <TimelineCreateDialog
+ open={dialog === "create"}
+ close={() => {
+ setDialog(null);
+ }}
+ />
</>
);
};
diff --git a/FrontEnd/src/views/common/dailog/ConfirmDialog.tsx b/FrontEnd/src/views/common/dailog/ConfirmDialog.tsx
index c10b1cdb..3817ce1e 100644
--- a/FrontEnd/src/views/common/dailog/ConfirmDialog.tsx
+++ b/FrontEnd/src/views/common/dailog/ConfirmDialog.tsx
@@ -6,7 +6,7 @@ import Button from "../button/Button";
import Dialog from "./Dialog";
const ConfirmDialog: React.FC<{
- open?: boolean;
+ open: boolean;
onClose: () => void;
onConfirm: () => void;
title: I18nText;
diff --git a/FrontEnd/src/views/common/dailog/Dialog.css b/FrontEnd/src/views/common/dailog/Dialog.css
index 6dd1a32e..21ea52fc 100644
--- a/FrontEnd/src/views/common/dailog/Dialog.css
+++ b/FrontEnd/src/views/common/dailog/Dialog.css
@@ -33,3 +33,23 @@
.cru-dialog-bottom-area > * {
margin: 0 0.5em;
}
+
+.cru-dialog-enter .cru-dialog-container {
+ transform: scale(0, 0);
+ opacity: 0;
+ transform-origin: center;
+}
+
+.cru-dialog-enter-active .cru-dialog-container {
+ transform: scale(1, 1);
+ opacity: 1;
+ transition: transform 0.3s, opacity 0.3s;
+ transform-origin: center;
+}
+
+.cru-dialog-exit-active .cru-dialog-container {
+ transition: transform 0.3s, opacity 0.3s;
+ transform: scale(0, 0);
+ opacity: 0;
+ transform-origin: center;
+}
diff --git a/FrontEnd/src/views/common/dailog/Dialog.tsx b/FrontEnd/src/views/common/dailog/Dialog.tsx
index ee58080f..ca733e3d 100644
--- a/FrontEnd/src/views/common/dailog/Dialog.tsx
+++ b/FrontEnd/src/views/common/dailog/Dialog.tsx
@@ -1,11 +1,12 @@
import React from "react";
import ReactDOM from "react-dom";
+import { CSSTransition } from "react-transition-group";
import "./Dialog.css";
export interface DialogProps {
onClose: () => void;
- open?: boolean;
+ open: boolean;
children?: React.ReactNode;
disableCloseOnClickOnOverlay?: boolean;
}
@@ -13,27 +14,33 @@ export interface DialogProps {
export default function Dialog(props: DialogProps): React.ReactElement | null {
const { open, onClose, children, disableCloseOnClickOnOverlay } = props;
- return open
- ? ReactDOM.createPortal(
+ return ReactDOM.createPortal(
+ <CSSTransition
+ mountOnEnter
+ unmountOnExit
+ in={open}
+ timeout={300}
+ classNames="cru-dialog"
+ >
+ <div
+ className="cru-dialog-overlay"
+ onClick={
+ disableCloseOnClickOnOverlay
+ ? undefined
+ : () => {
+ onClose();
+ }
+ }
+ >
<div
- className="cru-dialog-overlay"
- onClick={
- disableCloseOnClickOnOverlay
- ? undefined
- : () => {
- onClose();
- }
- }
+ className="cru-dialog-container"
+ onClick={(e) => e.stopPropagation()}
>
- <div
- className="cru-dialog-container"
- onClick={(e) => e.stopPropagation()}
- >
- {children}
- </div>
- </div>,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- document.getElementById("portal")!
- )
- : null;
+ {children}
+ </div>
+ </div>
+ </CSSTransition>,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ document.getElementById("portal")!
+ );
}
diff --git a/FrontEnd/src/views/common/dailog/FullPageDialog.css b/FrontEnd/src/views/common/dailog/FullPageDialog.css
index fd125a5a..2f1fc636 100644
--- a/FrontEnd/src/views/common/dailog/FullPageDialog.css
+++ b/FrontEnd/src/views/common/dailog/FullPageDialog.css
@@ -42,7 +42,3 @@
transition: transform 0.3s;
transform: translate(100%, 0);
}
-
-.cru-full-page-exit-done {
- display: none;
-}
diff --git a/FrontEnd/src/views/common/dailog/FullPageDialog.tsx b/FrontEnd/src/views/common/dailog/FullPageDialog.tsx
index 2aff9f2e..45454b7d 100644
--- a/FrontEnd/src/views/common/dailog/FullPageDialog.tsx
+++ b/FrontEnd/src/views/common/dailog/FullPageDialog.tsx
@@ -18,7 +18,13 @@ const FullPageDialog: React.FC<FullPageDialogProps> = ({
contentContainerClassName,
}) => {
return createPortal(
- <CSSTransition in={show} timeout={300} classNames="cru-full-page">
+ <CSSTransition
+ mountOnEnter
+ unmountOnExit
+ in={show}
+ timeout={300}
+ classNames="cru-full-page"
+ >
<div className="cru-full-page">
<div className="cru-full-page-top-bar">
<i
diff --git a/FrontEnd/src/views/settings/index.tsx b/FrontEnd/src/views/settings/index.tsx
index 69a74327..b9a8209b 100644
--- a/FrontEnd/src/views/settings/index.tsx
+++ b/FrontEnd/src/views/settings/index.tsx
@@ -84,32 +84,29 @@ const SettingsPage: React.FC = (_) => {
</div>
</Card>
</div>
- {(() => {
- switch (dialog) {
- case "changepassword":
- return <ChangePasswordDialog open close={() => setDialog(null)} />;
- case "logout":
- return (
- <ConfirmDialog
- title="settings.dialogConfirmLogout.title"
- body="settings.dialogConfirmLogout.prompt"
- onClose={() => setDialog(null)}
- open
- onConfirm={() => {
- void userService.logout().then(() => {
- history.push("/");
- });
- }}
- />
- );
- case "changeavatar":
- return <ChangeAvatarDialog open close={() => setDialog(null)} />;
- case "changenickname":
- return <ChangeNicknameDialog open close={() => setDialog(null)} />;
- default:
- return null;
- }
- })()}
+ <ChangePasswordDialog
+ open={dialog === "changepassword"}
+ close={() => setDialog(null)}
+ />
+ <ConfirmDialog
+ title="settings.dialogConfirmLogout.title"
+ body="settings.dialogConfirmLogout.prompt"
+ onClose={() => setDialog(null)}
+ open={dialog === "logout"}
+ onConfirm={() => {
+ void userService.logout().then(() => {
+ history.push("/");
+ });
+ }}
+ />
+ <ChangeAvatarDialog
+ open={dialog === "changeavatar"}
+ close={() => setDialog(null)}
+ />
+ <ChangeNicknameDialog
+ open={dialog === "changenickname"}
+ close={() => setDialog(null)}
+ />
</>
);
};
diff --git a/FrontEnd/src/views/timeline-common/MarkdownPostEdit.tsx b/FrontEnd/src/views/timeline-common/MarkdownPostEdit.tsx
index 300b3d9d..42ba37de 100644
--- a/FrontEnd/src/views/timeline-common/MarkdownPostEdit.tsx
+++ b/FrontEnd/src/views/timeline-common/MarkdownPostEdit.tsx
@@ -190,15 +190,13 @@ const MarkdownPostEdit: React.FC<MarkdownPostEditProps> = ({
},
]}
/>
- {showLeaveConfirmDialog && (
- <ConfirmDialog
- onClose={() => setShowLeaveConfirmDialog(false)}
- onConfirm={onClose}
- open
- title="timeline.dropDraft"
- body="timeline.confirmLeave"
- />
- )}
+ <ConfirmDialog
+ onClose={() => setShowLeaveConfirmDialog(false)}
+ onConfirm={onClose}
+ open={showLeaveConfirmDialog}
+ title="timeline.dropDraft"
+ body="timeline.confirmLeave"
+ />
</>
);
};
diff --git a/FrontEnd/src/views/timeline-common/PostPropertyChangeDialog.tsx b/FrontEnd/src/views/timeline-common/PostPropertyChangeDialog.tsx
index 988124b6..c1dd416c 100644
--- a/FrontEnd/src/views/timeline-common/PostPropertyChangeDialog.tsx
+++ b/FrontEnd/src/views/timeline-common/PostPropertyChangeDialog.tsx
@@ -5,17 +5,18 @@ import { getHttpTimelineClient, HttpTimelinePostInfo } from "@/http/timeline";
import OperationDialog from "../common/dailog/OperationDialog";
function PostPropertyChangeDialog(props: {
+ open: boolean;
onClose: () => void;
post: HttpTimelinePostInfo;
onSuccess: (post: HttpTimelinePostInfo) => void;
}): React.ReactElement | null {
- const { onClose, post, onSuccess } = props;
+ const { open, onClose, post, onSuccess } = props;
return (
<OperationDialog
title="timeline.changePostPropertyDialog.title"
onClose={onClose}
- open
+ open={open}
inputScheme={[
{
label: "timeline.changePostPropertyDialog.time",
diff --git a/FrontEnd/src/views/timeline-common/TimelineMember.tsx b/FrontEnd/src/views/timeline-common/TimelineMember.tsx
index 0ebecbb9..59d4c371 100644
--- a/FrontEnd/src/views/timeline-common/TimelineMember.tsx
+++ b/FrontEnd/src/views/timeline-common/TimelineMember.tsx
@@ -186,7 +186,7 @@ export const TimelineMemberDialog: React.FC<TimelineMemberDialogProps> = (
props
) => {
return (
- <Dialog open onClose={props.onClose}>
+ <Dialog open={props.open} onClose={props.onClose}>
<TimelineMember {...props} />
</Dialog>
);
diff --git a/FrontEnd/src/views/timeline-common/TimelinePageCardTemplate.tsx b/FrontEnd/src/views/timeline-common/TimelinePageCardTemplate.tsx
index 844bece3..eb17a9d0 100644
--- a/FrontEnd/src/views/timeline-common/TimelinePageCardTemplate.tsx
+++ b/FrontEnd/src/views/timeline-common/TimelinePageCardTemplate.tsx
@@ -134,27 +134,18 @@ const TimelinePageCardTemplate: React.FC<TimelineCardTemplateProps> = ({
<div style={{ display: collapse ? "none" : "inline" }}>{content}</div>
)}
</Card>
- {(() => {
- if (dialog === "member") {
- return (
- <TimelineMemberDialog
- timeline={timeline}
- onClose={() => setDialog(null)}
- open
- onChange={onReload}
- />
- );
- } else if (dialog === "property") {
- return (
- <TimelinePropertyChangeDialog
- timeline={timeline}
- close={() => setDialog(null)}
- open
- onChange={onReload}
- />
- );
- }
- })()}
+ <TimelineMemberDialog
+ timeline={timeline}
+ onClose={() => setDialog(null)}
+ open={dialog === "member"}
+ onChange={onReload}
+ />
+ <TimelinePropertyChangeDialog
+ timeline={timeline}
+ close={() => setDialog(null)}
+ open={dialog === "property"}
+ onChange={onReload}
+ />
</>
);
};
diff --git a/FrontEnd/src/views/timeline-common/TimelinePostView.tsx b/FrontEnd/src/views/timeline-common/TimelinePostView.tsx
index de6c3e7c..086176f8 100644
--- a/FrontEnd/src/views/timeline-common/TimelinePostView.tsx
+++ b/FrontEnd/src/views/timeline-common/TimelinePostView.tsx
@@ -124,36 +124,34 @@ const TimelinePostView: React.FC<TimelinePostViewProps> = (props) => {
</div>
) : null}
</Card>
- {dialog === "delete" ? (
- <ConfirmDialog
- title="timeline.post.deleteDialog.title"
- body="timeline.post.deleteDialog.prompt"
- open
- onClose={() => {
- setDialog(null);
- setOperationMaskVisible(false);
- }}
- onConfirm={() => {
- void getHttpTimelineClient()
- .deletePost(post.timelineName, post.id)
- .then(onDeleted, () => {
- pushAlert({
- type: "danger",
- message: "timeline.deletePostFailed",
- });
+ <ConfirmDialog
+ title="timeline.post.deleteDialog.title"
+ body="timeline.post.deleteDialog.prompt"
+ open={dialog === "delete"}
+ onClose={() => {
+ setDialog(null);
+ setOperationMaskVisible(false);
+ }}
+ onConfirm={() => {
+ void getHttpTimelineClient()
+ .deletePost(post.timelineName, post.id)
+ .then(onDeleted, () => {
+ pushAlert({
+ type: "danger",
+ message: "timeline.deletePostFailed",
});
- }}
- />
- ) : dialog === "changeproperty" ? (
- <PostPropertyChangeDialog
- onClose={() => {
- setDialog(null);
- setOperationMaskVisible(false);
- }}
- post={post}
- onSuccess={onChanged}
- />
- ) : null}
+ });
+ }}
+ />
+ <PostPropertyChangeDialog
+ open={dialog === "changeproperty"}
+ onClose={() => {
+ setDialog(null);
+ setOperationMaskVisible(false);
+ }}
+ post={post}
+ onSuccess={onChanged}
+ />
</div>
);
};
diff --git a/FrontEnd/src/views/timeline/TimelineCard.tsx b/FrontEnd/src/views/timeline/TimelineCard.tsx
index 56057560..339fbfa0 100644
--- a/FrontEnd/src/views/timeline/TimelineCard.tsx
+++ b/FrontEnd/src/views/timeline/TimelineCard.tsx
@@ -58,17 +58,11 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => {
setDialog={setDialog}
{...props}
/>
- {(() => {
- if (dialog === "delete") {
- return (
- <TimelineDeleteDialog
- timeline={timeline}
- open
- close={() => setDialog(null)}
- />
- );
- }
- })()}
+ <TimelineDeleteDialog
+ timeline={timeline}
+ open={dialog === "delete"}
+ close={() => setDialog(null)}
+ />
</>
);
};