implemented detail page of paper item.

This commit is contained in:
Yoshihiro OKUMURA
2019-05-09 23:03:34 +09:00
parent b1688a5535
commit 820f6ed8c7
6 changed files with 351 additions and 25 deletions
+142
View File
@@ -0,0 +1,142 @@
import React from 'react';
import { Link } from 'react-router-dom';
import ItemUtil, { ItemBasicLang, ItemBasicChangeLog, ItemBasicIndex } from './ItemUtil';
import IndexUtil from './IndexUtil';
import DatabaseItemType from '../components/DatabaseItemType';
class ItemTypeUtil {
static Language(props: { lang: ItemBasicLang }) {
const { lang } = props;
const langStr = {
eng: 'English',
jpn: 'Japanese',
fra: 'French',
deu: 'German',
esl: 'Spanish',
ita: 'Italian',
dut: 'Dutch',
sve: 'Swedish',
nor: 'Norwegian',
dan: 'Danish',
fin: 'Finnish',
por: 'Portuguese',
chi: 'Chinese',
kor: 'Korean',
}
if (!(lang in langStr)) {
return null;
}
const label = langStr[lang];
return (<span>{label}</span>);
}
static FreeKeyword(props: { keyword: string[] }) {
const { keyword } = props;
if (keyword.length === 0) {
return null;
}
const label = keyword.join(', ');
return (<span>{label}</span>);
}
static Contributer(props: { uname: string, name: string }) {
const { name, uname } = props;
const label = (name === '' ? uname : name + ' (' + uname + ')');
return (<span>{label}</span>);
}
static Date(props: { date: number }) {
const { date } = props;
const d = new Date(date * 1000);
const monthStr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const year = d.getFullYear();
const month = monthStr[d.getMonth()];
const mday = d.getDate();
const hour = d.getHours();
const min = d.getMinutes();
const sec = d.getSeconds();
const label = month + ' ' + mday + ', ' + year + ' ' + hour + ':' + min + ':' + sec;
return (<span>{label}</span>);
}
static ChangeLogDate(props: { date: number }) {
const { date } = props;
const d = new Date(date * 1000);
const monthStr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const year = d.getFullYear();
const month = monthStr[d.getMonth()];
const mday = d.getDate();
const label = month + ' ' + mday + ', ' + year + ' ';
return (<span>{label}</span>);
}
static ChangeLog(props: {changelog: ItemBasicChangeLog[]}) {
const { changelog } = props;
if (changelog.length === 0) {
return null;
}
const elements = changelog.map((value, index) => {
return (
<tr key={index}>
<td className="changeLogDate"><ItemTypeUtil.ChangeLogDate date={value.log_date} /></td>
<td>{value}</td>
</tr>
);
});
return (<table><tbody>{elements}</tbody></table>);
}
static Author(props: { author: string[] }) {
const { author } = props;
if (author.length === 0) {
return null;
}
let evenodd = 'even';
const elements = author.map((value, index) => {
evenodd = evenodd === 'even' ? 'odd' : 'even';
return (<tr key={index}><td className={evenodd}>{value}</td></tr>);
});
return (<table><tbody>{elements}</tbody></table>);
}
static Index(props: { index: ItemBasicIndex[] }) {
const { index } = props;
if (index.length === 0) {
return null;
}
let evenodd = 'even';
const elements = index.map((value, index) => {
evenodd = evenodd === 'even' ? 'odd' : 'even';
const url = IndexUtil.getUrl(value.index_id);
return (<tr key={index}><td className={evenodd}><Link to={url}>{value.title}</Link></td></tr>);
});
return (<table><tbody>{elements}</tbody></table>);
}
static RelatedTo(props: { relatedTo: number[] }) {
const { relatedTo } = props;
if (relatedTo.length === 0) {
return null;
}
let evenodd = 'even';
const elements = relatedTo.map((value) => {
const item = ItemUtil.get(value);
if (item === null) {
return null;
}
evenodd = evenodd === 'even' ? 'odd' : 'even';
return (<tr key={value}><td className={evenodd}><DatabaseItemType.List item={item} /></td></tr>);
});
return (
<table>
<tbody>
<tr><th>Item summary</th></tr>
{elements}
</tbody>
</table>
);
}
}
export default ItemTypeUtil;
+28 -18
View File
@@ -1,6 +1,23 @@
import loki from 'lokijs';
import itemsJson from '../assets/items.json';
export type ItemBasicLang = 'eng' | 'jpn' | 'fra' | 'deu' | 'esl' | 'ita' | 'dut' | 'sve' | 'nor' | 'dan' | 'fin' | 'por' | 'chi' | 'kor';
export interface ItemBasicIndex {
index_id: number;
title: string;
}
export interface ItemBasicChangeLog {
log_date: number;
log: string;
}
export interface ItemBasicFile {
file_id: number;
original_file_name: string;
mime_type: string;
file_size: number;
timestamp: string;
display_name: string;
}
export interface ItemBasic {
item_id: number;
item_type_id: number;
@@ -12,32 +29,18 @@ export interface ItemBasic {
publication_year: number;
publication_month: number;
publication_mday: number;
lang: string;
lang: ItemBasicLang;
title: string;
item_type_display_name: string;
item_type_name: string;
uname: string;
name: string;
item_url: string;
index: {
index_id: number;
title: string;
}[];
changelog: {
uid: number;
log_date: number;
log: string;
}[];
index: ItemBasicIndex[];
changelog: ItemBasicChangeLog[];
related_to: number[];
keyword: string[];
file: {
file_id: number;
original_file_name: string;
mime_type: string;
file_size: number;
timestamp: string;
display_name: string;
}[];
file: ItemBasicFile[];
}
export interface ItemBook extends ItemBasic {
@@ -204,6 +207,13 @@ class ItemUtil {
return items.findOne(filter);
}
static getByDoi(doi: string) {
const filter = {
'doi': doi
}
return items.findOne(filter);
}
static getListByIndexId(indexId: number, condition: SortCondition): SearchResult {
const filter = {
'index.index_id': indexId
+4 -1
View File
@@ -1,6 +1,7 @@
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import DatabaseItemType from './DatabaseItemType';
import DatabaseDetailItem from './DatabaseDetailItem';
import DatabaseSearchByIndexId from './DatabaseSearchByIndexId';
import DatabaseSearchByItemType from './DatabaseSearchByItemType';
import styles from './Database.module.css';
@@ -10,10 +11,12 @@ const Database = () => {
<div className={styles.database}>
<Switch>
<Route exact path="/database" component={DatabaseItemType.Top} />
<Route exact path="/database/item/:id" component={DatabaseDetailItem} />
<Route exact path="/database/item/id/:doi" component={DatabaseDetailItem} />
<Route exact path="/database/list" component={DatabaseSearchByIndexId} />
<Route path="/database/list/:id" component={DatabaseSearchByIndexId} />
<Route exact path="/database/itemtype/:itemType" component={DatabaseSearchByItemType} />
<Route path="/database/itemtype/:itemType/:subItemType" component={DatabaseSearchByItemType} />
<Route exact path="/database/itemtype/:itemType/:subItemType" component={DatabaseSearchByItemType} />
</Switch>
</div>
);
+57
View File
@@ -0,0 +1,57 @@
import React, { Component } from 'react';
import { RouteComponentProps } from 'react-router';
import ItemUtil, { Item } from '../common/ItemUtil';
import DatabaseItemType from './DatabaseItemType';
interface Props extends RouteComponentProps<{ id: string, doi: string }> { }
interface State {
item: Item | null;
}
class DatabaseDetailItem extends Component<Props, State> {
public state: State = {
item: null,
};
constructor(props: Props) {
super(props);
const { params } = this.props.match;
let item = null;
if (params.doi !== undefined) {
item = ItemUtil.getByDoi(params.doi);
} else if (params.id !== undefined) {
const itemId = parseInt(params.id, 10);
item = ItemUtil.get(itemId);
}
this.state.item = item;
}
componentWillReceiveProps(nextProps: Props) {
const { params } = nextProps.match;
let item = null;
if (params.doi !== undefined) {
item = ItemUtil.getByDoi(params.doi);
} else if (params.id !== undefined) {
const itemId = parseInt(params.id, 10);
item = ItemUtil.get(itemId);
}
this.setState({ item });
}
render() {
if (this.state.item === null) {
return (null);
}
return (
<>
<h3>Detail</h3>
<br />
<DatabaseItemType.Detail item={this.state.item} />
</>
);
}
}
export default DatabaseDetailItem;
+23 -3
View File
@@ -35,7 +35,7 @@ class DatabaseItemType {
<DatabaseItemTypeModel.Top />
</td>
<td className={styles.itemType}>
<DatabaseItemTypeUrl.Top />
<DatabaseItemTypeUrl.Top />
</td>
</tr>
</tbody>
@@ -43,7 +43,7 @@ class DatabaseItemType {
);
}
static List(props: {item:Item}) {
static List(props: { item: Item }) {
const item = props.item;
switch (item.item_type_name) {
case 'xnpbook':
@@ -59,7 +59,27 @@ class DatabaseItemType {
case 'xnpurl':
return (<DatabaseItemTypeUrl.List item={item as ItemUrl} />);
default:
return <div>ID:{item.item_id}</div>
return (null);
}
}
static Detail(props: { item: Item }) {
const item = props.item;
switch (item.item_type_name) {
case 'xnpbook':
return (<DatabaseItemTypeBook.List item={item as ItemBook} />);
case 'xnpconference':
return (<DatabaseItemTypeConference.List item={item as ItemConference} />);
case 'xnpdata':
return (<DatabaseItemTypeData.List item={item as ItemData} />);
case 'xnpmodel':
return (<DatabaseItemTypeModel.List item={item as ItemModel} />);
case 'xnppaper':
return (<DatabaseItemTypePaper.Detail item={item as ItemPaper} />);
case 'xnpurl':
return (<DatabaseItemTypeUrl.List item={item as ItemUrl} />);
default:
return (null);
}
}
}
+97 -3
View File
@@ -1,6 +1,7 @@
import React from 'react';
import { Link } from 'react-router-dom';
import ItemUtil, { ItemPaper } from '../common/ItemUtil';
import ItemTypeUtil from '../common/ItemTypeUtil';
import iconFile from '../assets/images/database/icon_paper.gif';
class DatabaseItemTypePaper {
@@ -37,9 +38,7 @@ class DatabaseItemTypePaper {
const volume = item.volume === null ? '' : ';' + String(item.volume);
const number = item.number === null ? '' : '(' + String(item.number) + ')';
const page = item.page === '' ? '' : ':' + item.page;
const pubmedUrl = 'https://www.ncbi.nlm.nih.gov/pubmed/' + item.pubmed_id;
const pubmedLink = (<a href={pubmedUrl} target="_blank" rel="noopener noreferrer">{item.pubmed_id}</a>);
const pubmed = item.pubmed_id === '' ? <></> : <span>[PMID: {pubmedLink}]</span>;
const pubmed = item.pubmed_id === '' ? <></> : <span>[PMID: <DatabaseItemTypePaper.PubmedLink pubmedId={item.pubmed_id} />]</span>;
return (
<table>
<tbody>
@@ -57,6 +56,101 @@ class DatabaseItemTypePaper {
</table>
);
}
static Detail(props: { item: ItemPaper }) {
const { item } = props;
return (
<table>
<tbody>
<tr>
<td className="head">ID</td>
<td className="odd">{item.doi}</td>
</tr>
<tr>
<td className="head">Language</td>
<td className="even"><ItemTypeUtil.Language lang={item.lang} /></td>
</tr>
<tr>
<td className="head">PubMedID</td>
<td className="odd"><DatabaseItemTypePaper.PubmedLink pubmedId={item.pubmed_id} /></td>
</tr>
<tr>
<td className="head">Title</td>
<td className="even">{item.title}</td>
</tr>
<tr>
<td className="head">Free Keywords</td>
<td className="odd"><ItemTypeUtil.FreeKeyword keyword={item.keyword} /></td>
</tr>
<tr>
<td className="head">Description</td>
<td className="even">{item.description}</td>
</tr>
<tr>
<td className="head">Last Modified Date</td>
<td className="odd"><ItemTypeUtil.Date date={item.last_update_date} /></td>
</tr>
<tr>
<td className="head">Created Date</td>
<td className="even"><ItemTypeUtil.Date date={item.creation_date} /></td>
</tr>
<tr>
<td className="head">Contributor</td>
<td className="odd"><ItemTypeUtil.Contributer uname={item.uname} name={item.name} /></td>
</tr>
<tr>
<td className="head">Item Type</td>
<td className="even">{item.item_type_display_name}</td>
</tr>
<tr>
<td className="head">Change Log(History)</td>
<td className="odd"><ItemTypeUtil.ChangeLog changelog={item.changelog} /></td>
</tr>
<tr>
<td className="head">Author</td>
<td className="even"><ItemTypeUtil.Author author={item.author} /></td>
</tr>
<tr>
<td className="head">Journal</td>
<td className="odd">{item.journal}</td>
</tr>
<tr>
<td className="head">Publication Year</td>
<td className="even">{item.publication_year}</td>
</tr>
<tr>
<td className="head">Volume</td>
<td className="odd">{item.volume}</td>
</tr>
<tr>
<td className="head">Number</td>
<td className="even">{item.number}</td>
</tr>
<tr>
<td className="head">Page</td>
<td className="odd">{item.page}</td>
</tr>
<tr>
<td className="head">Index</td>
<td className="even"><ItemTypeUtil.Index index={item.index} /></td>
</tr>
<tr>
<td className="head">Related to</td>
<td className="odd"><ItemTypeUtil.RelatedTo relatedTo={item.related_to} /></td>
</tr>
</tbody>
</table>
);
}
static PubmedLink(props: {pubmedId: string}) {
const {pubmedId} = props;
if (pubmedId === '') {
return null;
}
const url = 'https://www.ncbi.nlm.nih.gov/pubmed/' + pubmedId;
return (<a href={url} target="_blank" rel="noopener noreferrer">{pubmedId}</a>);
}
}
export default DatabaseItemTypePaper;