diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ef38070 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +/.tscache +/.idea +/build/ +/dist/ +node_modules/ +/src/**/*.js +/tests/**/*.js +*.map +*.css +*.log diff --git a/phovea.js b/phovea.js index c139042..6d559db 100644 --- a/phovea.js +++ b/phovea.js @@ -8,7 +8,9 @@ module.exports = function(registry) { //registry.push('extension-type', 'extension-id', function() { return System.import('./src/extension_impl'); }, {}); // generator-phovea:begin - + registry.push('app', 'valid', function() { return System.import('./src/'); }, { + 'name': 'VALID' + }); // generator-phovea:end }; diff --git a/src/app.js b/src/app.js index 6d9882b..a9658c7 100644 --- a/src/app.js +++ b/src/app.js @@ -1,14 +1,36 @@ /** - * Created by Caleydo Team on 31.08.2016. + * Main entry point of the whole application, where all views are loaded and created. + * + * Created by Valid Team on 10.04.2016. + * Framework Created by Caleydo Team on 31.08.2016. */ import * as d3 from 'd3'; -import { HELLO_WORLD } from './language'; +import * as plugins from 'phovea_core/src/plugin'; /** - * The main class for the App app + * The main class for the Valid app */ var App = (function () { function App(parent) { + /** + * Enter here the views you want to append. You can choose between either the + * 'dataLoadingView' --> Here the file dialog and load for data is placed + * 'dataVizView' --> This contains the final visualization + * + * @type {[{view: string; parent: string; options: {cssClass: string; eventName: string}}]} + */ + this.views = [ + { + view: 'Example', + parent: 'app', + options: { + cssClass: 'test', + eventName: 'testEvent' + } + } + ]; this.$node = d3.select(parent); + this.$node.append('div').classed('dataLoadingView', true); + this.$node.append('div').classed('dataVizView', true); } /** * Initialize the view and return a promise @@ -16,15 +38,48 @@ var App = (function () { * @returns {Promise} */ App.prototype.init = function () { + //This method is used to add the event listeners to the view + this.addListeners(); + //This method calls the build function which fills the DOM with elements return this.build(); }; + /** + * Initialize all necessary listeners here + */ + App.prototype.addListeners = function () { + //Add listeners here + }; /** * Load and initialize all necessary views * @returns {Promise} */ App.prototype.build = function () { - this.$node.html(HELLO_WORLD); - return Promise.resolve(null); + var _this = this; + this.setBusy(true); // show loading indicator before loading + // wrap view ids from package.json as plugin and load the necessary files + var pluginPromises = this.views + .map(function (d) { return plugins.get('validView', d.view); }) + .filter(function (d) { return d !== undefined; }) // filter views that does not exists + .map(function (d) { return d.load(); }); + // when everything is loaded, then create and init the views + var buildPromise = Promise.all(pluginPromises) + .then(function (plugins) { + _this.$node.select('h3').remove(); // remove loading text from index.html template + var initPromises = plugins.map(function (p, index) { + var view = p.factory(_this.$node.select("." + _this.views[index].parent).node(), // parent node + _this.views[index].options || {} // options + ); + return view.init(); + }); + // wait until all views are initialized, before going to next then + return Promise.all(initPromises); + }) + .then(function (viewInstances) { + // loading and initialization has finished -> hide loading indicator + _this.setBusy(false); + return _this; + }); + return buildPromise; }; /** * Show or hide the application loading indicator diff --git a/src/app.js.map b/src/app.js.map index 1842ff3..c415539 100644 --- a/src/app.js.map +++ b/src/app.js.map @@ -1 +1 @@ -{"version":3,"file":"app.js","sourceRoot":"","sources":["app.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAC,WAAW,EAAC,MAAM,YAAY,CAAC;AAEvC;;GAEG;AACH;IAIE,aAAY,MAAc;QACxB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,kBAAI,GAAJ;QACE,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED;;;OAGG;IACK,mBAAK,GAAb;QACE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7B,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACH,qBAAO,GAAP,UAAQ,MAAe;QACrB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC;IACxD,CAAC;IAEH,UAAC;AAAD,CAAC,AAlCD,IAkCC;;AAED;;;;GAIG;AACH,MAAM,iBAAiB,MAAc;IACnC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;AACzB,CAAC"} \ No newline at end of file +{"version":3,"file":"app.js","sourceRoot":"","sources":["app.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/app.ts b/src/app.ts index 415d6d0..d4e97b7 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,19 +1,68 @@ /** - * Created by Caleydo Team on 31.08.2016. + * Main entry point of the whole application, where all views are loaded and created. + * + * Created by Valid Team on 10.04.2016. + * Framework Created by Caleydo Team on 31.08.2016. */ import * as d3 from 'd3'; +import * as plugins from 'phovea_core/src/plugin'; import {HELLO_WORLD} from './language'; /** - * The main class for the App app + * Interface for all valid views */ -export class App { +export interface MAppViews { + /** + * Initialize the view and return a promise + * that is resolved as soon the view is completely initialized. + * @returns {Promise} + */ + init():Promise; +} + +/** + * Boilerplate for the views that are loaded + */ +interface MAppViewsDesc { + /** + * Consists of the view id, the parent node, and optional options to the view. + */ + view: string; + parent: string; + options: any; +} + +/** + * The main class for the Valid app + */ +export class App implements MAppViews { private $node; + /** + * Enter here the views you want to append. You can choose between either the + * 'dataLoadingView' --> Here the file dialog and load for data is placed + * 'dataVizView' --> This contains the final visualization + * + * @type {[{view: string; parent: string; options: {cssClass: string; eventName: string}}]} + */ + private views:MAppViewsDesc[] = [ + { + view: 'Example', + parent: 'app', + options: { + cssClass: 'test', + eventName: 'testEvent' + } + } + ]; + constructor(parent:Element) { this.$node = d3.select(parent); + + this.$node.append('div').classed('dataLoadingView', true); + this.$node.append('div').classed('dataVizView', true); } /** @@ -22,16 +71,55 @@ export class App { * @returns {Promise} */ init() { + //This method is used to add the event listeners to the view + this.addListeners(); + //This method calls the build function which fills the DOM with elements return this.build(); } + /** + * Initialize all necessary listeners here + */ + private addListeners() { + //Add listeners here + } + /** * Load and initialize all necessary views * @returns {Promise} */ private build() { - this.$node.html(HELLO_WORLD); - return Promise.resolve(null); + this.setBusy(true); // show loading indicator before loading + + // wrap view ids from package.json as plugin and load the necessary files + const pluginPromises = this.views + .map((d) => plugins.get('validView', d.view)) + .filter((d) => d !== undefined) // filter views that does not exists + .map((d) => d.load()); + + // when everything is loaded, then create and init the views + const buildPromise = Promise.all(pluginPromises) + .then((plugins) => { + this.$node.select('h3').remove(); // remove loading text from index.html template + + const initPromises = plugins.map((p, index) => { + const view = p.factory( + this.$node.select(`.${this.views[index].parent}`).node(), // parent node + this.views[index].options || {} // options + ); + return view.init(); + }); + + // wait until all views are initialized, before going to next then + return Promise.all(initPromises); + }) + .then((viewInstances) => { + // loading and initialization has finished -> hide loading indicator + this.setBusy(false); + return this; + }); + + return buildPromise; } /** diff --git a/src/index.js b/src/index.js index c494d62..6865c8f 100644 --- a/src/index.js +++ b/src/index.js @@ -6,7 +6,7 @@ import 'file-loader?name=404.html-loader!./404.html'; import 'file-loader?name=robots.txt!./robots.txt'; import 'phovea_ui/src/_bootstrap'; import './style.scss'; -import { create as createApp } from './app'; +import * as app from './app'; var parent = document.querySelector('#app'); -createApp(parent).init(); +app.create(parent).init(); //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/src/index.js.map b/src/index.js.map index 6d493d2..2f63375 100644 --- a/src/index.js.map +++ b/src/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,qEAAqE,CAAC;AAC7E,OAAO,6CAA6C,CAAC;AACrD,OAAO,0CAA0C,CAAC;AAClD,OAAO,0BAA0B,CAAC;AAClC,OAAO,cAAc,CAAC;AACtB,OAAO,EAAC,MAAM,IAAI,SAAS,EAAC,MAAM,OAAO,CAAC;AAK1C,IAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;AAC9C,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,qEAAqE,CAAC;AAC7E,OAAO,6CAA6C,CAAC;AACrD,OAAO,0CAA0C,CAAC;AAClD,OAAO,0BAA0B,CAAC;AAClC,OAAO,cAAc,CAAC;AACtB,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAK7B,IAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;AAC9C,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC"} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index f2b619d..2350f9a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,10 +7,10 @@ import 'file-loader?name=404.html-loader!./404.html'; import 'file-loader?name=robots.txt!./robots.txt'; import 'phovea_ui/src/_bootstrap'; import './style.scss'; -import {create as createApp} from './app'; +import * as app from './app'; import {create as createHeader, AppHeaderLink} from 'phovea_ui/src/header'; import {APP_NAME} from './language'; const parent = document.querySelector('#app'); -createApp(parent).init(); +app.create(parent).init(); diff --git a/src/style.scss b/src/style.scss index f3952af..604e16b 100644 --- a/src/style.scss +++ b/src/style.scss @@ -3,3 +3,11 @@ */ @import 'styles/vars'; @import 'styles/base'; + +.dataLoadingView { + +} + +.dataVizView { + +}