pinkmine/frontend/src/misc-components/issue-details-dialog.tsx

99 lines
No EOL
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<RedmineTypes.ExtendedIssue>()
}).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<typeof Store>
};
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 (
<div className={Css.modal} style={props.store.displayStyle}>
<div className={Css.modalContent}>
<h1>
<button onClick={(e) => {e.stopPropagation(); props.store.hide();}}>close</button>
<IssueHrefNs.IssueHref
id={props.store.issue?.id || -1}
subject={props.store.issue?.subject || ''}
tracker={props.store.issue?.tracker?.name || ''}
url={props.store.issue?.url?.url || ''}
/>
</h1>
<hr/>
<div>
<h2>Описание:</h2>
<pre>
{props.store.issue.description}
</pre>
</div>
<hr/>
<div>
<h2>Комментарии:</h2>
<Comments details={props.store.issue.journals || []} issue={props.store.issue}/>
</div>
</div>
</div>
);
});
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 <Comment data={detail} key={key}/>
});
return (
<>{list}</>
);
}
export const Comment = (props: {data: RedmineTypes.Journal}): JSX.Element => {
console.debug(`Comment: data=${JSON.stringify(props.data)}`); // DEBUG
return (
<>
<h3>{props.data.user.name}:</h3>
<div>
<pre>
{props.data.notes || '-'}
</pre>
</div>
<hr/>
</>
);
}