plugin.ts 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import {
  4. h, VNode
  5. } from 'phosphor/lib/ui/vdom';
  6. import {
  7. JupyterLab, JupyterLabPlugin
  8. } from '../application';
  9. import {
  10. ICommandPalette
  11. } from '../commandpalette';
  12. import {
  13. VDomModel, VDomWidget
  14. } from '../common/vdom';
  15. /**
  16. * The faq page extension.
  17. */
  18. export
  19. const faqExtension: JupyterLabPlugin<void> = {
  20. id: 'jupyter.extensions.faq',
  21. requires: [ICommandPalette],
  22. activate: activateFAQ,
  23. autoStart: true
  24. };
  25. class FaqModel extends VDomModel {
  26. }
  27. class FaqWidget extends VDomWidget<FaqModel> {
  28. constructor(app: JupyterLab) {
  29. super();
  30. const basicsQuestions = [
  31. 'What is JupyterLab?',
  32. 'What is a Jupyter Notebook?',
  33. 'How stable is JupyterLab?',
  34. 'I\'m confused with the interface. How do I navigate around JupyterLab?'
  35. ];
  36. const featuresQuestions = [
  37. 'How do I add more kernels/languages to JupyterLab?',
  38. 'How can I share my notebooks?'
  39. ];
  40. const developerQuestions = [
  41. 'How do I report a bug?',
  42. 'I have security concerns about JupyterLab.',
  43. 'How can I contribute?'
  44. ];
  45. // Create Frequently Asked Questions Header Section.
  46. let faqHeader =
  47. h.section({id: 'faq-header'},
  48. h.span({className: 'jp-QuestionMark jp-FAQ-QuestionMark'}),
  49. h.h1({className: 'jp-FAQ-h1'},
  50. h.span({className: 'jp-FAQ-title'},
  51. 'Frequently Asked Questions'
  52. )
  53. )
  54. );
  55. // Create a section element that holds Table of Contents.
  56. let questionList =
  57. h.section({className: 'jp-FAQ-content', id: 'faq-questionList'},
  58. h.h2({className: 'jp-FAQ-h2'}, 'THE BASICS'),
  59. h.ul({className: 'jp-FAQ-ul'},
  60. h.li({className: 'jp-FAQ-question jp-FAQ-toc'},
  61. h.a({href: '#basicsQ1'}, basicsQuestions[0])
  62. ),
  63. h.li({className: 'jp-FAQ-question jp-FAQ-toc'},
  64. h.a({href: '#basicsQ2'}, basicsQuestions[1])
  65. ),
  66. h.li({className: 'jp-FAQ-question jp-FAQ-toc'},
  67. h.a({href: '#basicsQ3'}, basicsQuestions[2])
  68. ),
  69. h.li({className: 'jp-FAQ-question jp-FAQ-toc'},
  70. h.a({href: '#basicsQ4'}, basicsQuestions[3])
  71. )
  72. ),
  73. h.h2({className: 'jp-FAQ-h2'}, 'FEATURES'),
  74. h.ul({className: 'jp-FAQ-ul'},
  75. h.li({className: 'jp-FAQ-question jp-FAQ-toc'},
  76. h.a({href: '#featuresQ1'}, featuresQuestions[0])
  77. ),
  78. h.li({className: 'jp-FAQ-question jp-FAQ-toc'},
  79. h.a({href: '#featuresQ2'}, featuresQuestions[1])
  80. )
  81. ),
  82. h.h2({className: 'jp-FAQ-h2'}, 'DEVELOPER'),
  83. h.ul({className: 'jp-FAQ-ul'},
  84. h.li({className: 'jp-FAQ-question jp-FAQ-toc'},
  85. h.a({href: '#developerQ1'}, developerQuestions[0])
  86. ),
  87. h.li({className: 'jp-FAQ-question jp-FAQ-toc'},
  88. h.a({href: '#developerQ2'}, developerQuestions[1])
  89. ),
  90. h.li({className: 'jp-FAQ-question jp-FAQ-toc'},
  91. h.a({href: '#developerQ3'}, developerQuestions[2])
  92. )
  93. )
  94. );
  95. // Create a section element that all other FAQ Content will go under.
  96. let questionAnswerList =
  97. h.section({className: 'jp-FAQ-content'},
  98. h.h2({className: 'jp-FAQ-h2'}, 'THE BASICS'),
  99. // Create list of questions/answers under the Basics section.
  100. h.ul({className: 'jp-FAQ-ul'},
  101. h.li({className: 'jp-FAQ-question', id: 'basicsQ1'}, basicsQuestions[0]),
  102. h.li({className: 'jp-FAQ-answer'},
  103. 'JupyterLab allows users to arrange multiple Jupyter notebooks, '
  104. + 'text editors, terminals, output areas, etc. on a single page with multiple '
  105. + 'panels and tabs into one application. The codebase and UI of JupyterLab '
  106. + 'is based on a flexible plugin system that makes it easy to extend '
  107. + 'with new components.'
  108. ),
  109. h.li({className: 'jp-FAQ-question', id: 'basicsQ2'}, basicsQuestions[1]),
  110. h.li({className: 'jp-FAQ-answer'},
  111. 'Central to the project is the Jupyter Notebook, a web-based '
  112. + 'platform that allows users to combine live code, equations, narrative '
  113. + 'text, visualizations, interactive dashboards and other media. Together '
  114. + 'these building blocks make science and data reproducible across over '
  115. + '40 programming languages and combine to form what we call a computational '
  116. + 'narrative.'
  117. ),
  118. h.li({className: 'jp-FAQ-question', id: 'basicsQ3'}, basicsQuestions[2]),
  119. h.li({className: 'jp-FAQ-answer'},
  120. 'JupyterLab is currently in a alpha release and not ready for public use '
  121. + 'as new features and bug fixes are being added very frequently. We strongly '
  122. + 'recommend to backup your work before using JupyterLab. However, testing, '
  123. + 'development, and user feedback are greatly appreciated.'
  124. ),
  125. h.li({className: 'jp-FAQ-question', id: 'basicsQ4'}, basicsQuestions[3]),
  126. h.li({className: 'jp-FAQ-answer'},
  127. 'Check out the JupyterLab tour ',
  128. h.a({className: 'jp-FAQ-a',
  129. onclick: () => {
  130. app.commands.execute('about-jupyterlab:show', void 0);
  131. }},
  132. 'here'
  133. )
  134. )
  135. ),
  136. h.h2({className: 'jp-FAQ-h2'}, 'FEATURES'),
  137. // Create list of questions/answers under the Features section.
  138. h.ul({className: 'jp-FAQ-ul'},
  139. h.li({className: 'jp-FAQ-question', id: 'featuresQ1'}, featuresQuestions[0]),
  140. h.li({className: 'jp-FAQ-answer'},
  141. 'To add more languages to the JupyterLab you must install '
  142. + 'a new kernel. Installing a kernel is usually fairly simple and can be '
  143. + 'done with a couple terminal commands. However the instructions for installing '
  144. + 'kernels is different for each language. For further instructions, click ',
  145. h.a({className: 'jp-FAQ-a',
  146. href: 'http://jupyter.readthedocs.io/en/latest/install-kernel.html',
  147. target: '_blank'},
  148. 'this'
  149. ),
  150. ' link.'
  151. ),
  152. h.li({className: 'jp-FAQ-question', id: 'featuresQ2'}, featuresQuestions[1]),
  153. h.li({className: 'jp-FAQ-answer'},
  154. 'You can either publish your notebooks on GitHub or use a free service such as ',
  155. h.a({className: 'jp-FAQ-a', href: 'https://nbviewer.jupyter.org/', target: '_blank'},
  156. 'nbviewer.org'
  157. ),
  158. ' to render your notebooks online.'
  159. )
  160. ),
  161. h.h2({className: 'jp-FAQ-h2'}, 'DEVELOPER'),
  162. // Create list of questions/answers under the Developer section.
  163. h.ul({className: 'jp-FAQ-ul'},
  164. h.li({className: 'jp-FAQ-question', id: 'developerQ1'}, developerQuestions[0]),
  165. h.li({className: 'jp-FAQ-answer'},
  166. 'You can open an issue on our ',
  167. h.a({className: 'jp-FAQ-a',
  168. href: 'https://github.com/jupyter/jupyterlab/issues',
  169. target: '_blank'},
  170. 'github repository'
  171. ),
  172. '. Please check already opened issues before posting.'
  173. ),
  174. h.li({className: 'jp-FAQ-question', id: 'developerQ2'}, developerQuestions[1]),
  175. h.li({className: 'jp-FAQ-answer'},
  176. 'If you have any inquiries, concerns, or thought you found a security '
  177. + 'vulnerability, please write to use at ',
  178. h.a({className: 'jp-FAQ-a', href: 'mailto:security@jupyter.org'},
  179. 'security@jupyter.org'
  180. ),
  181. '. We will do our best to repond to you promptly.'
  182. ),
  183. h.li({className: 'jp-FAQ-question', id: 'developerQ3'}, developerQuestions[2]),
  184. h.li({className: 'jp-FAQ-answer'},
  185. 'There are many ways to contribute to JupyterLab. '
  186. + 'Whether you are an experienced python programmer or a newcomer, any '
  187. + 'interested developers are welcome. You can learn about the JupyterLab '
  188. + 'codebase by going through our ',
  189. h.a({className: 'jp-FAQ-a',
  190. href: 'http://jupyterlab-tutorial.readthedocs.io/en/latest/index.html',
  191. target: '_blank'},
  192. 'tutorial walkthrough'
  193. ),
  194. ' and ',
  195. h.a({className: 'jp-FAQ-a',
  196. href: 'http://jupyter.org/jupyterlab/',
  197. target: '_blank'},
  198. 'documentation'
  199. ),
  200. '. Also, feel free to ask questions on our ',
  201. h.a({className: 'jp-FAQ-a',
  202. href: 'https://github.com/jupyter/jupyterlab',
  203. target: '_blank'},
  204. 'github'
  205. ),
  206. ' or through any of our ',
  207. h.a({className: 'jp-FAQ-a',
  208. href: 'http://jupyter.org/community.html',
  209. target: '_blank'},
  210. 'community resources'
  211. ),
  212. '.'
  213. )
  214. )
  215. );
  216. this._data = [faqHeader, questionList, questionAnswerList];
  217. }
  218. protected render(): VNode[] {
  219. return this._data;
  220. }
  221. private _data: VNode[];
  222. }
  223. /**
  224. * Activate the faq plugin.
  225. */
  226. function activateFAQ(app: JupyterLab, palette: ICommandPalette): void {
  227. let faqModel = new FaqModel();
  228. let widget = new FaqWidget(app);
  229. let commandId = 'faq-jupyterlab:show';
  230. widget.model = faqModel;
  231. widget.id = 'faq-jupyterlab';
  232. widget.title.label = 'FAQ';
  233. widget.title.closable = true;
  234. widget.node.style.overflowY = 'auto';
  235. app.commands.addCommand(commandId, {
  236. label: 'Frequently Asked Questions',
  237. execute: () => {
  238. if (!widget.isAttached) {
  239. app.shell.addToMainArea(widget);
  240. }
  241. app.shell.activateMain(widget.id);
  242. }
  243. });
  244. palette.addItem({ command: commandId, category: 'Help' });
  245. }