diff options
-rw-r--r-- | FrontEnd/src/views/admin/UserAdmin.tsx | 344 | ||||
-rw-r--r-- | FrontEnd/src/views/center/index.tsx | 14 | ||||
-rw-r--r-- | FrontEnd/src/views/common/dailog/ConfirmDialog.tsx | 2 | ||||
-rw-r--r-- | FrontEnd/src/views/common/dailog/Dialog.css | 20 | ||||
-rw-r--r-- | FrontEnd/src/views/common/dailog/Dialog.tsx | 51 | ||||
-rw-r--r-- | FrontEnd/src/views/common/dailog/FullPageDialog.css | 4 | ||||
-rw-r--r-- | FrontEnd/src/views/common/dailog/FullPageDialog.tsx | 8 | ||||
-rw-r--r-- | FrontEnd/src/views/settings/index.tsx | 49 | ||||
-rw-r--r-- | FrontEnd/src/views/timeline-common/MarkdownPostEdit.tsx | 16 | ||||
-rw-r--r-- | FrontEnd/src/views/timeline-common/PostPropertyChangeDialog.tsx | 5 | ||||
-rw-r--r-- | FrontEnd/src/views/timeline-common/TimelineMember.tsx | 2 | ||||
-rw-r--r-- | FrontEnd/src/views/timeline-common/TimelinePageCardTemplate.tsx | 33 | ||||
-rw-r--r-- | FrontEnd/src/views/timeline-common/TimelinePostView.tsx | 56 | ||||
-rw-r--r-- | FrontEnd/src/views/timeline/TimelineCard.tsx | 16 |
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)} + /> </> ); }; |