From 44934a590c5036b3528fe17668ee70f925c140bd Mon Sep 17 00:00:00 2001 From: Pavel Gnedov Date: Mon, 19 Jun 2023 20:44:05 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=BC=D0=BE=D0=B4=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE?= =?UTF-8?q?=D0=B5=20=D0=BE=D0=BA=D0=BD=D0=BE=20=D0=B4=D0=BB=D1=8F=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=81=D0=BC=D0=BE=D1=82=D1=80=D0=B0=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=80=D0=B8=D0=B5=D0=B2=20?= =?UTF-8?q?=D0=BA=20=D0=B7=D0=B0=D0=B4=D0=B0=D1=87=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../issues-list-board/issues-list-card.tsx | 8 +- .../src/kanban-board/kanban-card.module.css | 2 +- frontend/src/kanban-board/kanban-card.tsx | 20 ++-- .../issue-details-dialog.module.css | 21 ++++ .../misc-components/issue-details-dialog.tsx | 99 +++++++++++++++++++ 5 files changed, 141 insertions(+), 9 deletions(-) create mode 100644 frontend/src/misc-components/issue-details-dialog.module.css create mode 100644 frontend/src/misc-components/issue-details-dialog.tsx diff --git a/frontend/src/issues-list-board/issues-list-card.tsx b/frontend/src/issues-list-board/issues-list-card.tsx index efaf706..72a995f 100644 --- a/frontend/src/issues-list-board/issues-list-card.tsx +++ b/frontend/src/issues-list-board/issues-list-card.tsx @@ -5,14 +5,20 @@ import Css from './issues-list-card.module.css'; import * as TimePassedNs from '../misc-components/time-passed'; import * as TagsNs from '../misc-components/tags'; import * as IssueHrefNs from '../misc-components/issue-href'; +import * as IssueDetailsDialogNs from '../misc-components/issue-details-dialog'; export type Props = { store: IIssueStore }; export const IssuesListCard = observer((props: Props): JSX.Element => { + const detailsStore = IssueDetailsDialogNs.Store.create({ + issue: props.store, + visible: false + }); return ( -
+
{e.stopPropagation(); e.preventDefault(); detailsStore.show();}}> +
diff --git a/frontend/src/kanban-board/kanban-card.module.css b/frontend/src/kanban-board/kanban-card.module.css index 17fde41..0810e9a 100644 --- a/frontend/src/kanban-board/kanban-card.module.css +++ b/frontend/src/kanban-board/kanban-card.module.css @@ -10,7 +10,7 @@ /*display: flex;*/ box-shadow: 0 0 3px rgba(0, 0, 0, 0.5); border-radius: 3px; - z-index: 100; + /* z-index: 100; */ } .kanbanCard div { diff --git a/frontend/src/kanban-board/kanban-card.tsx b/frontend/src/kanban-board/kanban-card.tsx index 41824e2..f2764be 100644 --- a/frontend/src/kanban-board/kanban-card.tsx +++ b/frontend/src/kanban-board/kanban-card.tsx @@ -5,6 +5,7 @@ import { ICardStore } from './store'; import { getStyleObjectFromString } from '../utils/style'; import * as TimePassedNs from '../misc-components/time-passed'; import * as TagsNs from '../misc-components/tags'; +import * as IssueDetailsDialogNs from '../misc-components/issue-details-dialog'; export type Props = { store: ICardStore @@ -49,18 +50,23 @@ export const KanbanCard = observer((props: Props) => { keyName: 'timePassedClass' } } + const detailsStore = IssueDetailsDialogNs.Store.create({ + issue: props.store.issue, + visible: false, + }) return ( -
+
{e.preventDefault(); e.stopPropagation(); detailsStore.show();}}> +
{props.store.issue.tracker.name} #{props.store.issue.id} - {props.store.issue.subject} -
Исп.: {props.store.issue.current_user.name}
-
Прио.: {props.store.issue.priority.name}
-
Версия: {props.store.issue.fixed_version?.name || ''}
-
Прогресс: {props.store.issue.done_ratio}
-
Трудозатраты: {props.store.issue.total_spent_hours} / {props.store.issue.total_estimated_hours}
- {tagsSection}
+
Исп.: {props.store.issue.current_user.name}
+
Прио.: {props.store.issue.priority.name}
+
Версия: {props.store.issue.fixed_version?.name || ''}
+
Прогресс: {props.store.issue.done_ratio}
+
Трудозатраты: {props.store.issue.total_spent_hours} / {props.store.issue.total_estimated_hours}
+ {tagsSection}
); }); diff --git a/frontend/src/misc-components/issue-details-dialog.module.css b/frontend/src/misc-components/issue-details-dialog.module.css new file mode 100644 index 0000000..5a40573 --- /dev/null +++ b/frontend/src/misc-components/issue-details-dialog.module.css @@ -0,0 +1,21 @@ +.modal { + z-index: 1000; + position: fixed; + display: none; + padding-top: 100px; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgb(0, 0, 0); + background-color: rgba(0, 0, 0, 0.4); +} + +.modalContent { + background-color: #fefefe; + margin: auto; + padding: 20px; + border: 1px solid #888; + width: 80%; +} \ No newline at end of file diff --git a/frontend/src/misc-components/issue-details-dialog.tsx b/frontend/src/misc-components/issue-details-dialog.tsx new file mode 100644 index 0000000..c33be89 --- /dev/null +++ b/frontend/src/misc-components/issue-details-dialog.tsx @@ -0,0 +1,99 @@ +import React, { useEffect } from 'react'; +import { RedmineTypes } from '../redmine-types'; +import { observer } from 'mobx-react-lite'; +import { Instance, types } from 'mobx-state-tree'; +import * as IssueHrefNs from '../misc-components/issue-href'; +import Css from './issue-details-dialog.module.css'; + +export const Store = types.model({ + visible: types.boolean, + issue: types.frozen() +}).actions((self) => { + return { + hide: () => { + console.debug(`Issue details dialog hide: issue_id=${self.issue.id}`); // DEBUG + self.visible = false; + }, + show: () => { + console.debug(`Issue details dialog show: issue_id=${self.issue.id}`); // DEBUG + self.visible = true; + } + }; +}).views((self) => { + return { + get displayStyle(): React.CSSProperties { + return {display: self.visible ? 'block' : 'none'}; + } + }; +}); + +export type Props = { + store: Instance +}; + +export const IssueDetailsDialog = observer((props: Props): JSX.Element => { + // DEBUG: begin + useEffect(() => { + console.debug(`Issue detailts dialog: issue_id=${props.store.issue.id}; subject=${props.store.issue?.subject || '-'}; description=${props.store.issue.description}; visible=${props.store.visible}`); + }); + // DEBUG: end + return ( +
+
+

+ + +

+
+
+

Описание:

+
+						{props.store.issue.description}
+					
+
+
+
+

Комментарии:

+ +
+
+
+ ); +}); + +export const Comments = (props: {details?: RedmineTypes.Journal[], issue: RedmineTypes.ExtendedIssue}): JSX.Element => { + const comments = props.details?.filter((detail) => { + return Boolean(detail.notes); + }); + if (!comments) { + return <>No comments + } + console.debug(`Comments: details=${JSON.stringify(props.details)}`); // DEBUG + const list = comments.map((detail) => { + const key = `issueid_${props.issue.id}_commentid_${detail.id}`; + return + }); + return ( + <>{list} + ); +} + +export const Comment = (props: {data: RedmineTypes.Journal}): JSX.Element => { + console.debug(`Comment: data=${JSON.stringify(props.data)}`); // DEBUG + return ( + <> +

{props.data.user.name}:

+
+
+					{props.data.notes || '-'}
+				
+
+
+ + ); +} \ No newline at end of file