diff options
Diffstat (limited to 'FrontEnd/src/pages')
-rw-r--r-- | FrontEnd/src/pages/timeline/Timeline.css | 7 | ||||
-rw-r--r-- | FrontEnd/src/pages/timeline/Timeline.tsx | 15 | ||||
-rw-r--r-- | FrontEnd/src/pages/timeline/TimelineCard.css | 18 | ||||
-rw-r--r-- | FrontEnd/src/pages/timeline/TimelineCard.tsx | 59 | ||||
-rw-r--r-- | FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx | 4 | ||||
-rw-r--r-- | FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx | 4 |
6 files changed, 55 insertions, 52 deletions
diff --git a/FrontEnd/src/pages/timeline/Timeline.css b/FrontEnd/src/pages/timeline/Timeline.css index 4dd4fdcc..f071f163 100644 --- a/FrontEnd/src/pages/timeline/Timeline.css +++ b/FrontEnd/src/pages/timeline/Timeline.css @@ -230,13 +230,6 @@ margin-right: 0.6em; } -.timeline-card { - position: fixed; - z-index: 1029; - top: 56px; - right: 0; - margin: 0.5em; -} .timeline-top { position: sticky; diff --git a/FrontEnd/src/pages/timeline/Timeline.tsx b/FrontEnd/src/pages/timeline/Timeline.tsx index 3a7fbd00..f93e1623 100644 --- a/FrontEnd/src/pages/timeline/Timeline.tsx +++ b/FrontEnd/src/pages/timeline/Timeline.tsx @@ -41,7 +41,7 @@ const Timeline: React.FC<TimelineProps> = (props) => { const [timeline, setTimeline] = React.useState<HttpTimelineInfo | null>(null); const [posts, setPosts] = React.useState<HttpTimelinePostInfo[] | null>(null); const [signalrState, setSignalrState] = React.useState<HubConnectionState>( - HubConnectionState.Connecting + HubConnectionState.Connecting, ); const [error, setError] = React.useState< "offline" | "forbid" | "notfound" | "error" | null @@ -81,7 +81,7 @@ const Timeline: React.FC<TimelineProps> = (props) => { console.error(error); setError("error"); } - } + }, ); }, [timelineOwner, timelineName, timelineReloadKey]); @@ -91,7 +91,7 @@ const Timeline: React.FC<TimelineProps> = (props) => { .then( (page) => { setPosts( - page.items.filter((p): p is HttpTimelinePostInfo => !p.deleted) + page.items.filter((p): p is HttpTimelinePostInfo => !p.deleted), ); setTotalPage(page.totalPageCount); }, @@ -106,14 +106,14 @@ const Timeline: React.FC<TimelineProps> = (props) => { console.error(error); setError("error"); } - } + }, ); }, [timelineOwner, timelineName, postsReloadKey]); React.useEffect(() => { const timelinePostUpdate$ = getTimelinePostUpdate$( timelineOwner, - timelineName + timelineName, ); const subscription = timelinePostUpdate$.subscribe(({ update, state }) => { if (update) { @@ -134,7 +134,7 @@ const Timeline: React.FC<TimelineProps> = (props) => { .then( (page) => { const ps = page.items.filter( - (p): p is HttpTimelinePostInfo => !p.deleted + (p): p is HttpTimelinePostInfo => !p.deleted, ); setPosts((old) => [...(old ?? []), ...ps]); }, @@ -149,7 +149,7 @@ const Timeline: React.FC<TimelineProps> = (props) => { console.error(error); setError("error"); } - } + }, ); }, currentPage < totalPage); @@ -183,7 +183,6 @@ const Timeline: React.FC<TimelineProps> = (props) => { {timeline == null && posts == null && <TimelineLoading />} {timeline && ( <TimelineCard - className="timeline-card" timeline={timeline} connectionStatus={signalrState} onReload={updateTimeline} diff --git a/FrontEnd/src/pages/timeline/TimelineCard.css b/FrontEnd/src/pages/timeline/TimelineCard.css new file mode 100644 index 00000000..75ce6c51 --- /dev/null +++ b/FrontEnd/src/pages/timeline/TimelineCard.css @@ -0,0 +1,18 @@ +.timeline-card { + position: fixed; + z-index: 1029; + top: 56px; + right: 0; + margin: 0.5em; +} + +.timeline-card-title { + display: inline-block; + vertical-align: middle; + color: var(--cru-key-on-color); +} + +.timeline-card-title-name { + margin-inline-start: 1em; + color: var(--cru-surface-on-color); +}
\ No newline at end of file diff --git a/FrontEnd/src/pages/timeline/TimelineCard.tsx b/FrontEnd/src/pages/timeline/TimelineCard.tsx index 8ce133c0..bcdfa4c2 100644 --- a/FrontEnd/src/pages/timeline/TimelineCard.tsx +++ b/FrontEnd/src/pages/timeline/TimelineCard.tsx @@ -1,5 +1,4 @@ -import * as React from "react"; -import { useTranslation } from "react-i18next"; +import { useState } from "react"; import classnames from "classnames"; import { HubConnectionState } from "@microsoft/signalr"; @@ -10,6 +9,8 @@ import { pushAlert } from "@/services/alert"; import { HttpTimelineInfo } from "@/http/timeline"; import { getHttpBookmarkClient } from "@/http/bookmark"; +import { useC } from "@/views/common/common"; +import { useDialog } from "@/views/common/dialog"; import UserAvatar from "@/views/common/user/UserAvatar"; import PopupMenu from "@/views/common/menu/PopupMenu"; import FullPageDialog from "@/views/common/dialog/FullPageDialog"; @@ -21,36 +22,36 @@ import { TimelineMemberDialog } from "./TimelineMember"; import TimelinePropertyChangeDialog from "./TimelinePropertyChangeDialog"; import IconButton from "@/views/common/button/IconButton"; -export interface TimelinePageCardProps { +import "./TimelineCard.css"; + +interface TimelinePageCardProps { timeline: HttpTimelineInfo; connectionStatus: HubConnectionState; - className?: string; onReload: () => void; } -const TimelineCard: React.FC<TimelinePageCardProps> = (props) => { - const { timeline, connectionStatus, onReload, className } = props; +export default function TimelineCard(props: TimelinePageCardProps) { + const { timeline, connectionStatus, onReload } = props; - const { t } = useTranslation(); + const user = useUser(); - const [dialog, setDialog] = React.useState< - "member" | "property" | "delete" | null - >(null); + const c = useC(); - const [collapse, setCollapse] = React.useState(true); + const [collapse, setCollapse] = useState(true); const toggleCollapse = (): void => { setCollapse((o) => !o); }; const isSmallScreen = useIsSmallScreen(); - const user = useUser(); + const { createDialogSwitch, dialog, dialogPropsMap, switchDialog } = + useDialog(["member", "property", "delete"]); const content = ( - <> - <h3 className="cru-color-primary d-inline-block align-middle"> + <div className="cru-primary"> + <h3 className="timeline-card-title"> {timeline.title} - <small className="ms-3 cru-color-secondary">{timeline.nameV2}</small> + <small className="timeline-card-title-name">{timeline.nameV2}</small> </h3> <div> <UserAvatar @@ -64,7 +65,7 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => { </div> <p className="mb-0">{timeline.description}</p> <small className="mt-1 d-block"> - {t(timelineVisibilityTooltipTranslationMap[timeline.visibility])} + {c(timelineVisibilityTooltipTranslationMap[timeline.visibility])} </small> <div className="mt-2 cru-text-end"> {user != null ? ( @@ -92,7 +93,7 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => { <IconButton icon="people" className="me-3" - onClick={() => setDialog("member")} + onClick={createDialogSwitch("member")} /> {timeline.manageable ? ( <PopupMenu @@ -100,12 +101,12 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => { { type: "button", text: "timeline.manageItem.property", - onClick: () => setDialog("property"), + onClick: createDialogSwitch("property"), }, { type: "divider" }, { type: "button", - onClick: () => setDialog("delete"), + onClick: createDialogSwitch("delete"), color: "danger", text: "timeline.manageItem.delete", }, @@ -116,12 +117,12 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => { </PopupMenu> ) : null} </div> - </> + </div> ); return ( <> - <Card className={classnames("p-2 cru-clearfix", className)}> + <Card className="timeline-card"> <div className={classnames( "cru-float-right d-flex align-items-center", @@ -145,23 +146,15 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => { </Card> <TimelineMemberDialog timeline={timeline} - onClose={() => setDialog(null)} - open={dialog === "member"} onChange={onReload} + {...dialogPropsMap["member"]} /> <TimelinePropertyChangeDialog timeline={timeline} - close={() => setDialog(null)} - open={dialog === "property"} onChange={onReload} + {...dialogPropsMap["property"]} /> - <TimelineDeleteDialog - timeline={timeline} - open={dialog === "delete"} - close={() => setDialog(null)} - /> + <TimelineDeleteDialog timeline={timeline} {...dialogPropsMap["delete"]} /> </> ); -}; - -export default TimelineCard; +} diff --git a/FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx b/FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx index d5b22aee..0a5a2491 100644 --- a/FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx +++ b/FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx @@ -9,7 +9,7 @@ import OperationDialog from "@/views/common/dialog/OperationDialog"; interface TimelineDeleteDialog { timeline: HttpTimelineInfo; open: boolean; - close: () => void; + onClose: () => void; } const TimelineDeleteDialog: React.FC<TimelineDeleteDialog> = (props) => { @@ -20,7 +20,7 @@ const TimelineDeleteDialog: React.FC<TimelineDeleteDialog> = (props) => { return ( <OperationDialog open={props.open} - onClose={props.close} + onClose={props.onClose} title="timeline.deleteDialog.title" color="danger" inputPrompt={() => ( diff --git a/FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx b/FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx index e26df3eb..b57135bb 100644 --- a/FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx +++ b/FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx @@ -12,7 +12,7 @@ import OperationDialog from "@/views/common/dialog/OperationDialog"; export interface TimelinePropertyChangeDialogProps { open: boolean; - close: () => void; + onClose: () => void; timeline: HttpTimelineInfo; onChange: () => void; } @@ -64,7 +64,7 @@ const TimelinePropertyChangeDialog: React.FC< }, }} open={props.open} - onClose={props.close} + onClose={props.onClose} onProcess={({ title, visibility, description }) => { const req: HttpTimelinePatchRequest = {}; if (title !== timeline.title) { |