Browse Source

Merge pull request #166 from blink1073/landing-page

Add a launcher
Dave Willmer 9 years ago
parent
commit
965049ab4e

+ 4 - 0
examples/lab/index.css

@@ -0,0 +1,4 @@
+/*-----------------------------------------------------------------------------
+| Copyright (c) Jupyter Development Team.
+| Distributed under the terms of the Modified BSD License.
+|----------------------------------------------------------------------------*/

+ 3 - 2
examples/lab/index.html

@@ -3,11 +3,12 @@
 <head>
   <title>Jupyter Plugins Demo</title>
   <link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
+  <link href="index.css" rel="stylesheet">
   <script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_CHTML-full,Safe&amp;delayStartupUntil=configured"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.js"></script>
-  <script id='jupyter-config-data' type="application/json">{ "baseUrl": "{{base_url}}", "wsUrl": "{{ws_url}}" }</script>
-  <script src="build/bundle.js" main="index"></script>
 </head>
 <body>
+  <script id='jupyter-config-data' type="application/json">{ "baseUrl": "{{base_url}}", "wsUrl": "{{ws_url}}" }</script>
+  <script src="build/bundle.js" main="index"></script>
 </body>
 </html>

+ 1 - 1
examples/lab/index.js

@@ -9,7 +9,6 @@ require('es6-promise').polyfill();
 
 require('jupyter-js-plugins/lib/default-theme/index.css');
 
-
 var app = new phosphide.Application({
   extensions: [
     require('phosphide/lib/extensions/commandpalette').commandPaletteExtension,
@@ -21,6 +20,7 @@ var app = new phosphide.Application({
     require('jupyter-js-plugins/lib/notebook/plugin').notebookHandlerExtension,
     require('jupyter-js-plugins/lib/shortcuts/plugin').shortcutsExtension,
     require('jupyter-js-plugins/lib/about/plugin').aboutExtension,
+    require('jupyter-js-plugins/lib/landing/plugin').landingExtension,
     require('jupyter-js-plugins/lib/main/plugin').mainExtension,
   ],
   providers: [

+ 2 - 2
examples/lab/webpack.conf.js

@@ -17,8 +17,8 @@ module.exports = {
       { test: /\.css$/, loader: 'style-loader!css-loader' },
       { test: /\.json$/, loader: 'json-loader' },
       { test: /\.html$/, loader: 'file' },
-      // jquery-ui loads some images
-      { test: /\.(jpg|png|gif)$/, loader: "file" }
+      // Handle image
+      { test: /\.(jpg|png|gif|svg)$/, loader: "file" },
     ]
   }
 }

+ 3 - 2
package.json

@@ -52,7 +52,7 @@
     "clean": "rimraf docs && rimraf lib && rimraf test/build",
     "clean:example": "rimraf example/build",
     "build:example": "cd example && npm run update && npm run build",
-    "build:src": "tsc --project src && node scripts/copycss.js",
+    "build:src": "tsc --project src && node scripts/copyfiles.js",
     "build:test": "tsc --project test/src && webpack --config test/webpack.conf.js",
     "build": "npm run build:src && npm run build:test",
     "docs": "typedoc --mode file --module commonjs --excludeNotExported --target es5 --moduleResolution node --out docs/ src",
@@ -83,7 +83,8 @@
     "lib/*.js",
     "lib/**/*.css",
     "lib/**/*.d.ts",
-    "lib/**/*.js"
+    "lib/**/*.js",
+    "lib/**/*.svg"
   ],
   "author": "Project Jupyter",
   "license": "BSD-3-Clause",

+ 1 - 0
scripts/copycss.js → scripts/copyfiles.js

@@ -1,2 +1,3 @@
 var fs = require('fs-extra');
 fs.copySync('src/', 'lib/', { filter: /\.css$/ });
+fs.copySync('src/', 'lib/', { filter: /\.svg$/ });

+ 0 - 1
src/about/plugin.ts

@@ -57,7 +57,6 @@ function activateAbout(app: Application): void {
 
 <p>Opening a notebook will open a minimally featured notebook. Code execution, Markdown rendering, and basic cell toolbar actions are supported.  Future versions will add more features from the existing Jupyter notebook.</p>
 `;
-    app.shell.addToMainArea(widget);
 
     app.commands.add([{
       id: commandId,

+ 2 - 0
src/default-theme/index.css

@@ -9,6 +9,8 @@
 @import './commandpalette.css';
 @import './help.css';
 @import './about.css';
+@import '../landing/index.css';
+
 
 body {
   margin: 0;

+ 9 - 0
src/filehandler/plugin.ts

@@ -52,5 +52,14 @@ function activateFileHandler(app: Application, registry: FileHandlerRegistry, se
     'New Directory', dirCreator.createNew.bind(dirCreator));
   registry.addCreator('New File', fileCreator.createNew.bind(fileCreator));
 
+  app.commands.add([
+  {
+    id: 'text-file:create-new',
+    handler: () => {
+      fileCreator.createNew('').then(contents => {
+        registry.open(contents.path);
+      });
+    }
+  }]);
   return Promise.resolve(void 0);
 };

+ 21 - 0
src/landing/images/jupyterlab.svg

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="740px" height="153px" viewBox="0 0 740 153" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 3.7.1 (28215) - http://www.bohemiancoding.com/sketch -->
+    <title>Group</title>
+    <desc>Created with Sketch.</desc>
+    <defs></defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="Group">
+            <path d="M21.612141,102.552661 C21.612141,121.752661 20.112141,128.052661 16.112141,132.652661 C12.612141,136.452661 6.812141,138.252661 0.212141,138.752661 L1.712141,150.152661 C9.512141,150.152661 20.012141,147.552661 26.512141,141.052661 C33.612141,133.752661 36.112141,123.652661 36.112141,108.152661 L36.112141,35.552661 L21.612141,35.552661 L21.612141,102.552661 L21.612141,102.552661 Z" id="Fill-1" fill="#404041"></path>
+            <path d="M130.212141,93.752661 C130.212141,102.052661 130.412141,109.252661 130.912141,115.552661 L118.012141,115.552661 L117.212141,102.452661 L116.912141,102.452661 C113.112141,108.852661 104.712141,117.352661 90.512141,117.352661 C77.912141,117.352661 62.912141,110.452661 62.912141,82.352661 L62.912141,35.552661 L77.412141,35.552661 L77.412141,79.852661 C77.412141,95.052661 82.012141,105.352661 95.312141,105.352661 C105.112141,105.352661 111.812141,98.552661 114.512141,92.152661 C115.312141,90.052661 115.812141,87.352661 115.812141,84.752661 L115.812141,35.552661 L130.312141,35.552661 L130.312141,93.752661 L130.212141,93.752661 Z" id="Fill-3" fill="#404041"></path>
+            <path d="M172.012141,83.052661 C172.012141,85.152661 172.312141,87.152661 172.712141,89.052661 C175.312141,99.152661 184.112141,106.052661 194.512141,106.052661 C209.912141,106.052661 218.812141,93.452661 218.812141,75.152661 C218.812141,59.152661 210.412141,45.352661 195.012141,45.352661 C185.112141,45.352661 175.812141,52.452661 173.012141,63.352661 C172.512141,65.152661 172.012141,67.352661 172.012141,69.352661 L172.012141,83.052661 L172.012141,83.052661 Z M157.612141,61.752661 C157.612141,51.552661 157.312141,43.252661 156.912141,35.652661 L170.012141,35.652661 L170.712141,49.352661 L171.012141,49.352661 C177.012141,39.552661 186.412141,33.852661 199.412141,33.852661 C218.712141,33.852661 233.312141,50.252661 233.312141,74.552661 C233.312141,103.352661 215.812141,117.552661 196.912141,117.552661 C186.312141,117.552661 177.112141,112.952661 172.312141,104.952661 L172.012141,104.952661 L172.012141,148.452661 L157.612141,148.452661 L157.612141,61.752661 L157.612141,61.752661 Z" id="Fill-5" fill="#404041"></path>
+            <path d="M259.087324,35.620872 L276.687324,82.920872 C278.487324,88.220872 280.487324,94.520872 281.787324,99.320872 L282.087324,99.320872 C283.587324,94.520872 285.187324,88.420872 287.187324,82.620872 L303.087324,35.620872 L318.487324,35.620872 L296.687324,92.620872 C286.287324,120.020872 279.187324,134.120872 269.287324,142.720872 C262.187324,149.020872 255.087324,151.520872 251.387324,152.120872 L247.687324,139.920872 C251.287324,138.720872 256.087324,136.420872 260.387324,132.820872 C264.387324,129.720872 269.287324,124.020872 272.587324,116.620872 C273.287324,115.120872 273.787324,114.020872 273.787324,113.120872 C273.787324,112.320872 273.487324,111.120872 272.787324,109.320872 L243.287324,35.620872 L259.087324,35.620872 L259.087324,35.620872 Z" id="Fill-7" fill="#404041"></path>
+            <path d="M356.712141,12.652661 L356.712141,35.652661 L377.512141,35.652661 L377.512141,46.652661 L356.712141,46.652661 L356.712141,89.752661 C356.712141,99.652661 359.512141,105.252661 367.612141,105.252661 C371.412141,105.252661 374.212141,104.752661 376.012141,104.252661 L376.712141,115.152661 C373.912141,116.352661 369.412141,117.152661 363.812141,117.152661 C357.012141,117.152661 351.612141,115.052661 348.112141,111.052661 C344.012141,106.752661 342.512141,99.652661 342.512141,90.252661 L342.512141,46.652661 L330.112141,46.652661 L330.112141,35.552661 L342.512141,35.552661 L342.512141,16.452661 L356.712141,12.652661 L356.712141,12.652661 Z" id="Fill-10" fill="#404041"></path>
+            <path d="M447.012141,67.852661 C447.212141,58.552661 443.212141,44.252661 426.812141,44.252661 C412.112141,44.252661 405.612141,57.852661 404.512141,67.852661 L447.012141,67.852661 L447.012141,67.852661 Z M404.312141,78.252661 C404.612141,97.952661 417.212141,106.052661 431.712141,106.052661 C442.112141,106.052661 448.412141,104.252661 453.912141,101.952661 L456.412141,112.352661 C451.312141,114.652661 442.512141,117.352661 429.812141,117.352661 C405.212141,117.352661 390.512141,101.152661 390.512141,77.052661 C390.512141,52.952661 404.712141,33.952661 428.012141,33.952661 C454.112141,33.952661 461.112141,56.952661 461.112141,71.652661 C461.112141,74.652661 460.812141,76.952661 460.612141,78.452661 L404.312141,78.452661 L404.312141,78.252661 Z" id="Fill-12" fill="#404041"></path>
+            <path d="M482.412141,60.552661 C482.412141,51.152661 482.212141,43.052661 481.712141,35.552661 L494.412141,35.552661 L494.912141,51.252661 L495.612141,51.252661 C499.212141,40.552661 508.012141,33.752661 517.812141,33.752661 C519.512141,33.752661 520.612141,33.952661 521.912141,34.252661 L521.912141,47.952661 C520.412141,47.652661 518.912141,47.452661 516.912141,47.452661 C506.712141,47.452661 499.412141,55.252661 497.412141,66.152661 C497.112141,68.152661 496.712141,70.452661 496.712141,72.952661 L496.712141,115.652661 L482.312141,115.652661 L482.312141,60.552661 L482.412141,60.552661 Z" id="Fill-14" fill="#404041"></path>
+            <polygon id="Shape" fill="#F37A3C" points="548.6 2.5 562.9 2.5 562.9 117.8 548.6 117.8"></polygon>
+            <path d="M630.4,116 L629.3,106.1 L628.8,106.1 C624.4,112.3 616,117.8 604.8,117.8 C588.9,117.8 580.8,106.6 580.8,95.2 C580.8,76.2 597.7,65.8 628,66 L628,64.4 C628,57.9 626.2,46.2 610.1,46.2 C602.8,46.2 595.2,48.5 589.6,52 L586.4,42.6 C592.9,38.4 602.3,35.6 612.2,35.6 C636.2,35.6 642.1,52 642.1,67.7 L642.1,97.1 C642.1,103.9 642.4,110.6 643.4,115.9 L630.4,115.9 L630.4,116 Z M628.3,75.9 C612.7,75.6 595,78.3 595,93.6 C595,102.9 601.2,107.2 608.5,107.2 C618.7,107.2 625.2,100.7 627.5,94.1 C628,92.6 628.3,91 628.3,89.6 L628.3,75.9 L628.3,75.9 Z" id="Shape" fill="#F37A3C"></path>
+            <path d="M664.5,116 C664.8,110.6 665.1,102.7 665.1,95.7 L665.1,0.7 L679.2,0.7 L679.2,50.1 L679.5,50.1 C684.5,41.3 693.6,35.7 706.3,35.7 C725.8,35.7 739.6,51.9 739.4,75.8 C739.4,103.9 721.7,117.8 704.2,117.8 C692.8,117.8 683.7,113.4 677.9,103 L677.4,103 L676.8,116 L664.5,116 L664.5,116 Z M679.3,84.5 C679.3,86.3 679.6,88.1 679.9,89.7 C682.7,99.6 690.9,106.4 701.3,106.4 C716.2,106.4 725.2,94.2 725.2,76.2 C725.2,60.5 717.1,47 701.8,47 C692.1,47 683,53.7 680,64.5 C679.7,66.1 679.2,68.1 679.2,70.3 L679.2,84.5 L679.3,84.5 Z" id="Shape" fill="#F37A3C"></path>
+        </g>
+    </g>
+</svg>

+ 49 - 0
src/landing/images/notebook.svg

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="389px" height="497px" viewBox="0 0 389 497" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 3.7.1 (28215) - http://www.bohemiancoding.com/sketch -->
+    <title>Group 13</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <linearGradient x1="50.7790723%" y1="14.7773143%" x2="49.1915472%" y2="82.8795422%" id="linearGradient-1">
+            <stop stop-color="#E4E4E4" offset="0%"></stop>
+            <stop stop-color="#FFFFFF" offset="100%"></stop>
+        </linearGradient>
+        <polygon id="path-2" points="34.7613934 0.0224090079 0.479592498 0.0224090079 0.479592498 34.3040697 34.7613934 34.3040697 34.7613934 0.0224090079"></polygon>
+        <polygon id="path-4" points="0.780441617 41.6167289 42.0410916 41.6167289 42.0410916 0.356351142 0.780441617 0.356351142 0.780441617 41.6167289"></polygon>
+    </defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="Group-13" transform="translate(1.555556, -2.187207)">
+            <g id="jupyter_filelogo-(1)" transform="translate(2.621520, 6.076389)" stroke-width="6.94444444" stroke="#9E9E9E">
+                <g id="jupyter_filelogo">
+                    <g id="Page-1">
+                        <g id="jupyter_filelogo">
+                            <g id="Group">
+                                <path d="M203.125,0 C267.604167,0 381.25,41.25 381.25,67.0833333 L381.25,489.583333 L0,489.583333 L0,0 L203.125,0 Z" id="path4338" fill-opacity="0.9903" fill="#FFFFFF"></path>
+                                <path d="M307.231995,69.5833333 C326.815329,58.9583333 380.234691,42.71026 381.172191,67.39776 C381.172191,25.52276 246.190329,0 201.398662,0 C235.669495,0 292.231995,13.3333333 307.231995,69.5833333 Z" id="path4384" fill="url(#linearGradient-1)"></path>
+                            </g>
+                        </g>
+                    </g>
+                </g>
+            </g>
+            <g id="Page-1" transform="translate(75.538187, 110.243056)">
+                <g id="Group-3" transform="translate(192.077210, 0.777913)">
+                    <mask id="mask-3" fill="white">
+                        <use xlink:href="#path-2"></use>
+                    </mask>
+                    <g id="Clip-2"></g>
+                    <path d="M34.7454068,16.4296443 C35.1503696,25.8878463 27.8122198,33.8830602 18.3540179,34.288023 C8.8958159,34.6937861 0.90060202,27.354836 0.495639235,17.896634 C0.089876128,8.43923237 7.42882621,0.443218163 16.8870282,0.0382553777 C26.3444298,-0.366707407 34.340444,6.97144235 34.7454068,16.4296443" id="Fill-1" fill="#6C6E70" mask="url(#mask-3)"></path>
+                </g>
+                <path d="M121.856503,246.650988 C69.4258275,246.650988 23.7682743,227.809014 0.000320128684,199.971424 C17.9867502,249.876284 65.7523508,285.557027 121.856503,285.557027 C177.960656,285.557027 225.726256,249.876284 243.712687,199.971424 C219.944732,227.809014 174.287179,246.650988 121.856503,246.650988" id="Fill-4" fill="#F27624"></path>
+                <path d="M121.856503,65.4671962 C174.287179,65.4671962 219.944732,84.3099706 243.712687,112.147561 C225.726256,62.2418997 177.960656,26.5611569 121.856503,26.5611569 C65.7523508,26.5611569 17.9867502,62.2418997 0.000320128684,112.147561 C23.7682743,84.3099706 69.4258275,65.4671962 121.856503,65.4671962" id="Fill-6" fill="#F27624"></path>
+                <g id="Group-10" transform="translate(12.805147, 280.090189)">
+                    <mask id="mask-5" fill="white">
+                        <use xlink:href="#path-4"></use>
+                    </mask>
+                    <g id="Clip-9"></g>
+                    <path d="M42.0218518,20.1035211 C42.5092477,31.4864968 33.6768973,41.109565 22.2939216,41.5977613 C10.9109459,42.0851572 1.2878777,33.2528068 0.799681452,21.8698311 C0.312285531,10.4860551 9.14463592,0.8629869 20.5276116,0.375590978 C31.9113876,-0.111804943 41.5344558,8.72054545 42.0218518,20.1035211" id="Fill-8" fill="#939597" mask="url(#mask-5)"></path>
+                </g>
+                <path d="M26.4133375,40.8845946 C26.7102569,47.8201825 21.3288937,53.6841397 14.3933058,53.9810591 C7.4569175,54.2779784 1.59376065,48.8966152 1.2968413,41.960227 C0.999121623,35.0246391 6.38128512,29.1614822 13.3168731,28.8645629 C20.252461,28.5668432 26.1164182,33.9490067 26.4133375,40.8845946" id="Fill-11" fill="#57585A"></path>
+            </g>
+        </g>
+    </g>
+</svg>

+ 13 - 0
src/landing/images/terminal.svg

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="385px" height="295px" viewBox="0 0 385 295" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 3.7.1 (28215) - http://www.bohemiancoding.com/sketch -->
+    <title>Group 8</title>
+    <desc>Created with Sketch.</desc>
+    <defs></defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="Group-8" transform="translate(-3.000000, 3.900814)">
+            <polygon id="Rectangle-8" stroke="#9E9E9E" stroke-width="6.80701754" fill="#000000" points="6.77490507 0 384.505641 0 384.505641 287.275871 6.79107044 287.275871"></polygon>
+            <path d="M118.07388,71.7411248 L49.7500088,98.4511413 L49.7500088,87.9307847 L105.566345,66.7731786 L49.7500088,45.674019 L49.7500088,35.1536624 L118.07388,61.9221253 L118.07388,71.7411248 Z M116.419457,112.302944 L116.419457,106.399855 L182.989935,106.399855 L182.989935,112.302944 L116.419457,112.302944 Z" id="&gt;_" fill="#FFFFFF"></path>
+        </g>
+    </g>
+</svg>

File diff suppressed because it is too large
+ 27 - 0
src/landing/images/texteditor.svg


+ 123 - 0
src/landing/index.css

@@ -0,0 +1,123 @@
+/*-----------------------------------------------------------------------------
+| Copyright (c) Jupyter Development Team.
+| Distributed under the terms of the Modified BSD License.
+|----------------------------------------------------------------------------*/
+.jp-Landing {
+  background: rgba(0,0,0,0.25);
+  color: #757575;
+  position: absolute;
+  z-index: 10000;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  top: 0px;
+  left: 0px;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+
+
+.jp-Landing-dialog {
+  padding-bottom: 20px;
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-size: 16px;
+  color: #757575;
+   background: #FAFAFA;
+  margin-left: auto;
+  margin-right: auto;
+  text-align: center;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+  border: 1px solid #BDBDBD;
+  border-radius: 2px;
+  box-shadow: 0px 2px 2px 0px rgba(0,0,0,0.5);
+}
+
+
+.jp-Landing-logo {
+  flex: 0 0 40px;
+  margin-left: auto;
+  margin-right: auto;
+  width: 100%;
+  background: white;
+  background-image: url(images/jupyterlab.svg);
+  background-size: 193px 40px;
+  background-repeat: no-repeat;
+  background-position: center top;
+  padding-bottom: 20px;
+  border-bottom: 1px solid #BDBDBD;
+}
+
+
+.jp-Landing-title {
+  padding-top: 20px;
+  background: white;
+  width: 100%;
+}
+
+
+.jp-Landing-header {
+  
+  padding-top: 20px;
+  padding-bottom: 8px;
+}
+
+
+.jp-Landing-body {
+  display: flex;
+  flex-direction: row;
+  padding-left: 20px;
+  padding-right: 20px;
+}
+
+
+.jp-Landing-column {
+  padding-left: 20px;
+  padding-right: 20px;
+  display: flex;
+  flex-direction: column;
+}
+
+
+.jp-Landing-image {
+  flex: 0 0 auto;
+  min-height: 72px;
+  max-height: 72px;
+  min-width: 56px;
+  max-width: 56px;
+  background-size: 56px 72px;
+  background-repeat: no-repeat;
+
+}
+
+
+.jp-Landing-image:hover {
+  cursor: pointer;
+}
+
+
+.jp-Landing-text {
+  flex: 0 0 auto;
+  font-size: 12px;
+  padding-top: 8px;
+}
+
+
+.jp-Landing-imageNotebook {
+  background-image: url(images/notebook.svg);
+}
+
+
+.jp-Landing-imageTerminal {
+  background-image: url(images/terminal.svg);
+}
+
+
+.jp-Landing-imageTextEditor {
+  background-image: url(images/texteditor.svg);
+}

+ 100 - 0
src/landing/plugin.ts

@@ -0,0 +1,100 @@
+// Copyright (c) Jupyter Development Team.
+// Distributed under the terms of the Modified BSD License.
+'use strict';
+
+import {
+  Application
+} from 'phosphide/lib/core/application';
+
+import {
+  Widget
+} from 'phosphor-widget';
+
+
+/**
+ * The landing page extension.
+ */
+export
+const landingExtension = {
+  id: 'jupyter.extensions.landing',
+  activate: activateLanding
+};
+
+
+function activateLanding(app: Application): void {
+  let widget = new Widget();
+  widget.id = 'landing-jupyterlab';
+  widget.title.text = 'JupyterLab';
+  widget.title.closable = true;
+  widget.addClass('jp-Landing');
+
+  let dialog = document.createElement('div');
+  dialog.className = 'jp-Landing-dialog';
+  widget.node.appendChild(dialog);
+
+  let title = document.createElement('span');
+  title.textContent = 'Welcome to';
+  title.className = 'jp-Landing-title';
+  dialog.appendChild(title);
+
+  let logo = document.createElement('span');
+  logo.className = 'jp-Landing-logo';
+  dialog.appendChild(logo);
+
+  let header = document.createElement('span');
+  header.textContent = 'Start a new activity:';
+  header.className = 'jp-Landing-header';
+  dialog.appendChild(header);
+
+  let body = document.createElement('div');
+  body.className = 'jp-Landing-body';
+  dialog.appendChild(body);
+
+  for (let name of ['Notebook', 'Terminal', 'Text Editor']) {
+    let column = document.createElement('div');
+    body.appendChild(column);
+    column.className = 'jp-Landing-column';
+
+    let img = document.createElement('span');
+    let imgName = name.replace(' ', '');
+    img.className = `jp-Landing-image${imgName} jp-Landing-image`;
+
+    column.appendChild(img);
+
+    let text = document.createElement('span');
+    text.textContent = name;
+    text.className = 'jp-Landing-text';
+    column.appendChild(text);
+  }
+
+  let img = body.getElementsByClassName('jp-Landing-imageNotebook')[0];
+  img.addEventListener('click', () => {
+    app.commands.execute('notebook:create-new');
+  });
+
+  img = body.getElementsByClassName('jp-Landing-imageTextEditor')[0];
+  img.addEventListener('click', () => {
+    app.commands.execute('text-file:create-new');
+  });
+
+  img = body.getElementsByClassName('jp-Landing-imageTerminal')[0];
+  img.addEventListener('click', () => {
+    app.commands.execute('terminal:create-new');
+  });
+
+  app.commands.add([{
+    id: 'jupyterlab-launcher:show',
+    handler: () => {
+      if (!widget.isAttached) app.shell.addToMainArea(widget);
+      app.shell.activateMain(widget.id);
+    }
+  }]);
+
+  app.palette.add([{
+    command: 'jupyterlab-launcher:show',
+    text: 'JupyterLab Launcher',
+    category: 'Help'
+  }]);
+
+  app.shell.addToMainArea(widget);
+}

+ 11 - 2
src/notebook/plugin.ts

@@ -79,7 +79,8 @@ const cmdIds = {
   toggleLinenumbers: 'notebook-cells:toggle-linenumbers',
   toggleAllLinenumbers: 'notebook:toggle-allLinenumbers',
   editMode: 'notebook-cells:editMode',
-  commandMode: 'notebook-cells:commandMode'
+  commandMode: 'notebook-cells:commandMode',
+  newNotebook: 'notebook:create-new'
 };
 
 
@@ -293,7 +294,15 @@ function activateNotebookHandler(app: Application, registry: FileHandlerRegistry
       let model = activeWidget.model;
       if (model) model.mode = 'edit';
     }
-  }
+  },
+  {
+    id: cmdIds['newNotebook'],
+    handler: () => {
+      creator.createNew('').then(contents => {
+        registry.open(contents.path);
+      });
+    }
+  },
   ]);
   app.palette.add([
   {

+ 1 - 1
src/terminal/plugin.ts

@@ -27,7 +27,7 @@ const terminalExtension = {
 
 function activateTerminal(app: Application): Promise<void> {
 
-  let newTerminalId = 'terminal:new';
+  let newTerminalId = 'terminal:create-new';
 
   app.commands.add([{
     id: newTerminalId,

Some files were not shown because too many files changed in this diff