123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- import {
- h, VNode
- } from 'phosphor/lib/ui/vdom';
- import {
- JupyterLab, JupyterLabPlugin
- } from '../application';
- import {
- ICommandPalette
- } from '../commandpalette';
- import {
- VDomModel, VDomWidget
- } from '../common/vdom';
- /**
- * The faq page extension.
- */
- export
- const faqExtension: JupyterLabPlugin<void> = {
- id: 'jupyter.extensions.faq',
- requires: [ICommandPalette],
- activate: activateFAQ,
- autoStart: true
- };
- /**
- * The class name added to the FAQ plugin.
- */
- const FAQ_CLASS = 'jp-FAQ';
- /**
- * The id name added to the header section element.
- */
- const HEADER_ID = 'faq-header';
- /**
- * The class name added to the title.
- */
- const TITLE_CLASS = 'jp-FAQ-title';
- /**
- * The class name added to h1 elements.
- */
- const HEADER_CLASS = 'jp-FAQ-h1';
- /**
- * The class name added to h2 elements.
- */
- const SUBHEADER_CLASS = 'jp-FAQ-h2';
- /**
- * The class name added for the question mark icon from default-theme.
- */
- const QUESTIONMARK_ICON_CLASS = 'jp-QuestionMark';
- /**
- * The class named added the question mark icon.
- */
- const QUESTIONMARK_CLASS = 'jp-FAQ-QuestionMark';
- /**
- * The class name added to faq content.
- */
- const CONTENT_CLASS = 'jp-FAQ-content';
- /**
- * The class name added to unordered list elements.
- */
- const FAQ_LIST_CLASS = 'jp-FAQ-ul';
- /**
- * The class name added to table of contents elements.
- */
- const TOC_CLASS = 'jp-FAQ-toc';
- /**
- * The class name added to questions.
- */
- const QUESTION_CLASS = 'jp-FAQ-question';
- /**
- * The class name added to answers.
- */
- const ANSWER_CLASS = 'jp-FAQ-answer';
- /**
- * The class name added to anchor elements.
- */
- const ANCHOR_CLASS = 'jp-FAQ-a';
- /**
- * FaqModel holds data which the FaqWidget will render.
- */
- class FaqModel extends VDomModel {
- // Title of the FAQ plugin.
- readonly title: string;
- // Contain subheadings for each section.
- readonly subHeadings: string[];
- // Contain questions for `the basics` section.
- readonly basicsQuestions: string[];
- // Contain questions for the `features` section.
- readonly featuresQuestions: string[];
- // Contain questions for the `developer` section.
- readonly developerQuestions: string[];
- /**
- * Construct a new faq model.
- */
- constructor() {
- super();
- this.title = 'Frequently Asked Questions';
- this.subHeadings = [
- 'THE BASICS',
- 'FEATURES',
- 'DEVELOPER'
- ];
- this.basicsQuestions = [
- 'What is JupyterLab?',
- 'What is a Jupyter Notebook?',
- 'How stable is JupyterLab?',
- 'I\'m confused with the interface. How do I navigate around JupyterLab?'
- ];
- this.featuresQuestions = [
- 'How do I add more kernels/languages to JupyterLab?',
- 'How can I share my notebooks?'
- ];
- this.developerQuestions = [
- 'How do I report a bug?',
- 'I have security concerns about JupyterLab.',
- 'How can I contribute?'
- ];
- }
- }
- /**
- * A virtual-DOM-based widget for the FAQ plugin.
- */
- class FaqWidget extends VDomWidget<FaqModel> {
- /**
- * Construct a new faq widget.
- */
- constructor(app: JupyterLab) {
- super();
- this._app = app;
- this.addClass(FAQ_CLASS);
- }
- /**
- * Render the faq plugin to virtual DOM nodes.
- */
- protected render(): VNode[] {
- let subHeadings = this.model.subHeadings;
- let basicsQuestions = this.model.basicsQuestions;
- let featuresQuestions = this.model.featuresQuestions;
- let developerQuestions = this.model.developerQuestions;
- // Create Frequently Asked Questions Header Section.
- let faqHeader =
- h.section({id: HEADER_ID},
- h.span({className: QUESTIONMARK_ICON_CLASS + ' ' + QUESTIONMARK_CLASS}),
- h.h1({className: HEADER_CLASS},
- h.span({className: TITLE_CLASS},
- this.model.title
- )
- )
- );
- // Create a section element that holds Table of Contents.
- let questionList =
- h.section({className: CONTENT_CLASS},
- h.h2({className: SUBHEADER_CLASS}, subHeadings[0]),
- h.ul({className: FAQ_LIST_CLASS},
- h.li({className: QUESTION_CLASS + ' ' + TOC_CLASS},
- h.a({href: '#basicsQ1'}, basicsQuestions[0])
- ),
- h.li({className: QUESTION_CLASS + ' ' + TOC_CLASS},
- h.a({href: '#basicsQ2'}, basicsQuestions[1])
- ),
- h.li({className: QUESTION_CLASS + ' ' + TOC_CLASS},
- h.a({href: '#basicsQ3'}, basicsQuestions[2])
- ),
- h.li({className: QUESTION_CLASS + ' ' + TOC_CLASS},
- h.a({href: '#basicsQ4'}, basicsQuestions[3])
- )
- ),
- h.h2({className: SUBHEADER_CLASS}, subHeadings[1]),
- h.ul({className: FAQ_LIST_CLASS},
- h.li({className: QUESTION_CLASS + ' ' + TOC_CLASS},
- h.a({href: '#featuresQ1'}, featuresQuestions[0])
- ),
- h.li({className: QUESTION_CLASS + ' ' + TOC_CLASS},
- h.a({href: '#featuresQ2'}, featuresQuestions[1])
- )
- ),
- h.h2({className: SUBHEADER_CLASS}, subHeadings[2]),
- h.ul({className: FAQ_LIST_CLASS},
- h.li({className: QUESTION_CLASS + ' ' + TOC_CLASS},
- h.a({href: '#developerQ1'}, developerQuestions[0])
- ),
- h.li({className: QUESTION_CLASS + ' ' + TOC_CLASS},
- h.a({href: '#developerQ2'}, developerQuestions[1])
- ),
- h.li({className: QUESTION_CLASS + ' ' + TOC_CLASS},
- h.a({href: '#developerQ3'}, developerQuestions[2])
- )
- )
- );
- // Create a section element that all other FAQ Content will go under.
- let questionAnswerList =
- h.section({className: CONTENT_CLASS},
- h.h2({className: SUBHEADER_CLASS}, subHeadings[0]),
- // Create list of questions/answers under the Basics section.
- h.ul({className: FAQ_LIST_CLASS},
- h.li({className: QUESTION_CLASS, id: 'basicsQ1'}, basicsQuestions[0]),
- h.li({className: ANSWER_CLASS},
- 'JupyterLab allows users to arrange multiple Jupyter notebooks, '
- + 'text editors, terminals, output areas, etc. on a single page with multiple '
- + 'panels and tabs into one application. The codebase and UI of JupyterLab '
- + 'is based on a flexible plugin system that makes it easy to extend '
- + 'with new components.'
- ),
- h.li({className: QUESTION_CLASS, id: 'basicsQ2'}, basicsQuestions[1]),
- h.li({className: ANSWER_CLASS},
- 'Central to the project is the Jupyter Notebook, a web-based '
- + 'platform that allows users to combine live code, equations, narrative '
- + 'text, visualizations, interactive dashboards and other media. Together '
- + 'these building blocks make science and data reproducible across over '
- + '40 programming languages and combine to form what we call a computational '
- + 'narrative.'
- ),
- h.li({className: QUESTION_CLASS, id: 'basicsQ3'}, basicsQuestions[2]),
- h.li({className: ANSWER_CLASS},
- 'JupyterLab is currently in a alpha release and not ready for public use '
- + 'as new features and bug fixes are being added very frequently. We strongly '
- + 'recommend to backup your work before using JupyterLab. However, testing, '
- + 'development, and user feedback are greatly appreciated.'
- ),
- h.li({className: QUESTION_CLASS, id: 'basicsQ4'}, basicsQuestions[3]),
- h.li({className: ANSWER_CLASS},
- 'Check out the JupyterLab tour ',
- h.a({className: ANCHOR_CLASS,
- onclick: () => {
- this._app.commands.execute('about-jupyterlab:show', void 0);
- }},
- 'here'
- )
- )
- ),
- h.h2({className: SUBHEADER_CLASS}, subHeadings[1]),
- // Create list of questions/answers under the Features section.
- h.ul({className: FAQ_LIST_CLASS},
- h.li({className: QUESTION_CLASS, id: 'featuresQ1'}, featuresQuestions[0]),
- h.li({className: ANSWER_CLASS},
- 'To add more languages to the JupyterLab you must install '
- + 'a new kernel. Installing a kernel is usually fairly simple and can be '
- + 'done with a couple terminal commands. However the instructions for installing '
- + 'kernels is different for each language. For further instructions, click ',
- h.a({className: ANCHOR_CLASS,
- href: 'https://jupyter.readthedocs.io/en/latest/install-kernel.html',
- target: '_blank'},
- 'this'
- ),
- ' link.'
- ),
- h.li({className: QUESTION_CLASS, id: 'featuresQ2'}, featuresQuestions[1]),
- h.li({className: ANSWER_CLASS},
- 'You can either publish your notebooks on GitHub or use a free service such as ',
- h.a({className: ANCHOR_CLASS, href: 'https://nbviewer.jupyter.org/', target: '_blank'},
- 'nbviewer.org'
- ),
- ' to render your notebooks online.'
- )
- ),
- h.h2({className: SUBHEADER_CLASS}, subHeadings[2]),
- // Create list of questions/answers under the Developer section.
- h.ul({className: FAQ_LIST_CLASS},
- h.li({className: QUESTION_CLASS, id: 'developerQ1'}, developerQuestions[0]),
- h.li({className: ANSWER_CLASS},
- 'You can open an issue on our ',
- h.a({className: ANCHOR_CLASS,
- href: 'https://github.com/jupyterlab/jupyterlab/issues',
- target: '_blank'},
- 'github repository'
- ),
- '. Please check already opened issues before posting.'
- ),
- h.li({className: QUESTION_CLASS, id: 'developerQ2'}, developerQuestions[1]),
- h.li({className: ANSWER_CLASS},
- 'If you have any inquiries, concerns, or thought you found a security '
- + 'vulnerability, please write to use at ',
- h.a({className: ANCHOR_CLASS, href: 'mailto:security@jupyter.org'},
- 'security@jupyter.org'
- ),
- '. We will do our best to repond to you promptly.'
- ),
- h.li({className: QUESTION_CLASS, id: 'developerQ3'}, developerQuestions[2]),
- h.li({className: ANSWER_CLASS},
- 'There are many ways to contribute to JupyterLab. '
- + 'Whether you are an experienced python programmer or a newcomer, any '
- + 'interested developers are welcome. You can learn about the JupyterLab '
- + 'codebase by going through our ',
- h.a({className: ANCHOR_CLASS,
- href: 'https://jupyterlab-tutorial.readthedocs.io/en/latest/index.html',
- target: '_blank'},
- 'tutorial walkthrough'
- ),
- ' and ',
- h.a({className: ANCHOR_CLASS,
- href: 'http://jupyter.org/jupyterlab/',
- target: '_blank'},
- 'documentation'
- ),
- '. Also, feel free to ask questions on our ',
- h.a({className: ANCHOR_CLASS,
- href: 'https://github.com/jupyterlab/jupyterlab',
- target: '_blank'},
- 'github'
- ),
- ' or through any of our ',
- h.a({className: ANCHOR_CLASS,
- href: 'http://jupyter.org/community.html',
- target: '_blank'},
- 'community resources'
- ),
- '.'
- )
- )
- );
- let domTree = [faqHeader, questionList, questionAnswerList];
- return domTree;
- }
- private _app: JupyterLab;
- }
- /**
- * Activate the faq plugin.
- */
- function activateFAQ(app: JupyterLab, palette: ICommandPalette): void {
- let faqModel = new FaqModel();
- let widget = new FaqWidget(app);
- let commandId = 'faq-jupyterlab:show';
- widget.model = faqModel;
- widget.id = 'faq-jupyterlab';
- widget.title.label = 'FAQ';
- widget.title.closable = true;
- widget.node.style.overflowY = 'auto';
- app.commands.addCommand(commandId, {
- label: 'Frequently Asked Questions',
- execute: () => {
- if (!widget.isAttached) {
- app.shell.addToMainArea(widget);
- }
- app.shell.activateMain(widget.id);
- }
- });
- palette.addItem({ command: commandId, category: 'Help' });
- }
|