|
1 import React from 'react'; |
|
2 import PropTypes from 'prop-types'; |
|
3 import { connect } from 'react-redux'; |
|
4 |
|
5 import { FormattedMessage } from 'react-intl'; |
|
6 import { |
|
7 Tab, |
|
8 Tabs, |
|
9 TabList, |
|
10 TabPanel, |
|
11 } from 'react-tabs'; |
|
12 |
|
13 import AnnotationsCards from '../ui/AnnotationsCards'; |
|
14 import DefinitionsCards from '../ui/DefinitionsCards'; |
|
15 import IssoThread from '../ui/IssoThread'; |
|
16 import { toBase64 } from '../utils'; |
|
17 |
|
18 import './term.scss'; |
|
19 |
|
20 const TermPage = ({ |
|
21 term, |
|
22 term64, |
|
23 defAndRef: defAndRefProp, |
|
24 messageId, |
|
25 activeTab, |
|
26 location, |
|
27 metacategories, |
|
28 topics, |
|
29 viaBaseUrl, |
|
30 discussionUrl, |
|
31 }) => { |
|
32 const defAndRef = defAndRefProp || { definitions: [], references: [] }; |
|
33 let { pathname } = location; |
|
34 const m = pathname.match(/(\/[^/]+\/[^/]+)(?:\/\d)?(?:\/.+)?/); |
|
35 pathname = m ? m[1] : pathname; |
|
36 return ( |
|
37 <div className="term-entry"> |
|
38 <h2>{term}</h2> |
|
39 <Tabs selectedTabPanelClassName="show active" selectedTabClassName="active" defaultIndex={activeTab || 0} forceRenderTabPanel> |
|
40 <TabList className="nav nav-tabs"> |
|
41 <Tab className="nav-item nav-link"> |
|
42 <FormattedMessage id="pages.glossary.definitions" defaultMessage="Definitions" /> |
|
43 {' ('} |
|
44 {defAndRef.definitions && defAndRef.definitions.length} |
|
45 {')'} |
|
46 </Tab> |
|
47 <Tab className="nav-item nav-link"> |
|
48 <FormattedMessage id="pages.glossary.references" defaultMessage="References" /> |
|
49 {' ('} |
|
50 {defAndRef.references && defAndRef.references.length} |
|
51 {')'} |
|
52 </Tab> |
|
53 <Tab className="nav-item nav-link"> |
|
54 <FormattedMessage id="pages.glossary.discussions" defaultMessage="Discussions" /> |
|
55 {' ('} |
|
56 {defAndRef.messagesCount} |
|
57 {')'} |
|
58 </Tab> |
|
59 </TabList> |
|
60 <div className="tab-content term-tab-content"> |
|
61 <TabPanel className="tab-pane fade"> |
|
62 <DefinitionsCards annotations={defAndRef.definitions} metacategories={metacategories}><h4 className="text-muted text-capitalize"><FormattedMessage id="page.term.noDefinition" defaultMessage="No definition yet" /></h4></DefinitionsCards> |
|
63 </TabPanel> |
|
64 <TabPanel className="tab-pane fade"> |
|
65 <AnnotationsCards |
|
66 annotations={defAndRef.references} |
|
67 viaBaseUrl={viaBaseUrl} |
|
68 metacategories={metacategories} |
|
69 categories={topics} |
|
70 > |
|
71 <h4 className="text-muted text-capitalize"> |
|
72 <FormattedMessage id="page.term.noReference" defaultMessage="No reference yet" /> |
|
73 </h4> |
|
74 </AnnotationsCards> |
|
75 </TabPanel> |
|
76 <TabPanel className="tab-pane fade"> |
|
77 <IssoThread |
|
78 issoId={term64} |
|
79 pathname={`${pathname}/2`} |
|
80 messageId={messageId} |
|
81 discussionUrl={discussionUrl} |
|
82 /> |
|
83 </TabPanel> |
|
84 </div> |
|
85 </Tabs> |
|
86 </div> |
|
87 ); |
|
88 }; |
|
89 |
|
90 TermPage.propTypes = { |
|
91 location: PropTypes.object.isRequired, |
|
92 term: PropTypes.string.isRequired, |
|
93 term64: PropTypes.string.isRequired, |
|
94 viaBaseUrl: PropTypes.string.isRequired, |
|
95 discussionUrl: PropTypes.string.isRequired, |
|
96 defAndRef: PropTypes.object, |
|
97 messageId: PropTypes.string, |
|
98 activeTab: PropTypes.number, |
|
99 metacategories: PropTypes.arrayOf(PropTypes.object).isRequired, |
|
100 topics: PropTypes.arrayOf(PropTypes.string).isRequired, |
|
101 dashboardId: PropTypes.string, // eslint-disable-line react/no-unused-prop-types |
|
102 }; |
|
103 |
|
104 TermPage.defaultProps = { |
|
105 defAndRef: {}, |
|
106 messageId: null, |
|
107 activeTab: 0, |
|
108 dashboardId: '', |
|
109 }; |
|
110 |
|
111 export default connect( |
|
112 (state, props) => { |
|
113 const { match, dashboardId } = props; |
|
114 const { params } = match; |
|
115 |
|
116 let { term } = (params || {}); |
|
117 term = term ? decodeURIComponent(term) : term; |
|
118 |
|
119 const defAndRef = term ? state.terms[term] : {}; |
|
120 |
|
121 const term64 = toBase64(dashboardId ? `${dashboardId}::${term}` : term); |
|
122 |
|
123 const { messageId } = (params || {}); |
|
124 |
|
125 const activeTab = Number((match.params || {}).activeTab || 0); |
|
126 |
|
127 return { |
|
128 term, |
|
129 term64, |
|
130 defAndRef, |
|
131 messageId, |
|
132 activeTab, |
|
133 }; |
|
134 }, |
|
135 )(TermPage); |