Attaching components to the tutorial
Change-Id: Ic24ec04872864421dc2b503f2e1c0cfed2852b0b
diff --git a/views/ngXosViews/UITutorial/bower.json b/views/ngXosViews/UITutorial/bower.json
index 009304e..0778e98 100644
--- a/views/ngXosViews/UITutorial/bower.json
+++ b/views/ngXosViews/UITutorial/bower.json
@@ -15,7 +15,8 @@
"tests"
],
"dependencies": {
- "josh.js": "teone/josh.js#~0.2.10"
+ "josh.js": "teone/josh.js#~0.2.10",
+ "angular-ui-ace": "bower"
},
"devDependencies": {
"jquery": "2.1.4",
diff --git a/views/ngXosViews/UITutorial/src/css/main.css b/views/ngXosViews/UITutorial/src/css/main.css
index d008cb5..cc63179 100644
--- a/views/ngXosViews/UITutorial/src/css/main.css
+++ b/views/ngXosViews/UITutorial/src/css/main.css
@@ -1,5 +1,7 @@
#xosUITutorial {
width: 100%; }
+ #xosUITutorial .ace_editor {
+ height: 200px; }
#xosUITutorial js-shell {
display: block; }
#xosUITutorial js-shell #shell-panel {
diff --git a/views/ngXosViews/UITutorial/src/index.html b/views/ngXosViews/UITutorial/src/index.html
index 00f0a42..17b625b 100644
--- a/views/ngXosViews/UITutorial/src/index.html
+++ b/views/ngXosViews/UITutorial/src/index.html
@@ -17,13 +17,14 @@
<!-- bower:js -->
<script src="vendor/jquery/dist/jquery.js"></script>
<script src="vendor/lodash/lodash.js"></script>
-<script src="vendor/josh.js/js/killring.js"></script>
<script src="vendor/josh.js/js/readline.js"></script>
<script src="vendor/josh.js/js/history.js"></script>
+<script src="vendor/josh.js/js/killring.js"></script>
<script src="vendor/josh.js/js/input.js"></script>
<script src="vendor/josh.js/js/pathhandler.js"></script>
<script src="vendor/josh.js/js/shell.js"></script>
<script src="vendor/angular/angular.js"></script>
+<script src="vendor/angular-ui-ace/ui-ace.js"></script>
<script src="vendor/angular-mocks/angular-mocks.js"></script>
<script src="vendor/angular-ui-router/release/angular-ui-router.js"></script>
<script src="vendor/angular-cookies/angular-cookies.js"></script>
@@ -36,13 +37,16 @@
<script src="vendor/angular-recursion/angular-recursion.js"></script>
<!-- endbower -->
<!-- endjs -->
+<script src="vendor/ace-builds/src-min-noconflict/ace.js"></script>
<!-- inject:js -->
<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
<script src="/.tmp/main.js"></script>
<script src="/.tmp/templateHandler.js"></script>
<script src="/.tmp/responseHandler.js"></script>
+<script src="/.tmp/playCmd.js"></script>
<script src="/.tmp/lessonsInfo.js"></script>
<script src="/.tmp/learnCmd.js"></script>
<script src="/.tmp/exploreCmd.js"></script>
<script src="/.tmp/errorHandler.js"></script>
+<script src="/.tmp/codeToString.js"></script>
<!-- endinject -->
\ No newline at end of file
diff --git a/views/ngXosViews/UITutorial/src/js/codeToString.js b/views/ngXosViews/UITutorial/src/js/codeToString.js
new file mode 100644
index 0000000..b8ae242
--- /dev/null
+++ b/views/ngXosViews/UITutorial/src/js/codeToString.js
@@ -0,0 +1,65 @@
+(function () {
+ angular.module('xos.UITutorial')
+ .service('codeToString', function(){
+ this.toString = code => {
+ if(angular.isArray(code)){
+ return code.map(item => this.toString(item));
+ }
+ else if(angular.isObject(code)){
+ let tmp = {};
+ Object.keys(code).forEach(key => {
+ tmp[key] = this.toString(code[key])
+ });
+ return tmp;
+ }
+ else{
+ return code.toString().split('\n').join('').replace(/ +(?= )/gmi, '');
+ }
+ };
+
+ this.toCode = string => {
+ let code;
+
+ try {
+ code = JSON.parse(string);
+ }
+ catch(e){
+ code = string;
+ }
+
+ if(angular.isArray(code)){
+ return code.map(item => this.toCode(item));
+ }
+ else if(angular.isObject(code)){
+ let tmp = {};
+ Object.keys(code).forEach(key => {
+ tmp[key] = this.toCode(code[key])
+ });
+ return tmp;
+ }
+ else{
+ if(!angular.isNumber(code) && code.indexOf('function') !== -1){
+ try {
+ return function(){
+ // create a closure to host our arguments
+ var func = new Function(`return ${code}`);
+
+ // invoke the original function passing arguments
+ func()(...arguments);
+ }
+ }
+ catch(e){
+ // in this case it is a string
+ return code;
+ }
+ }
+ else if(Number.isNaN(code)){
+ return parseFloat(code);
+ }
+ return code;
+ }
+
+ return code;
+ };
+ });
+})();
\ No newline at end of file
diff --git a/views/ngXosViews/UITutorial/src/js/main.js b/views/ngXosViews/UITutorial/src/js/main.js
index 627a560..a686fe6 100644
--- a/views/ngXosViews/UITutorial/src/js/main.js
+++ b/views/ngXosViews/UITutorial/src/js/main.js
@@ -4,7 +4,8 @@
'ngResource',
'ngCookies',
'ui.router',
- 'xos.helpers'
+ 'xos.helpers',
+ 'ui.ace'
])
.config(($stateProvider) => {
$stateProvider
@@ -16,14 +17,14 @@
.config(function($httpProvider){
$httpProvider.interceptors.push('NoHyperlinks');
})
-.directive('jsShell', function(TemplateHandler){
+.directive('jsShell', function($rootScope, TemplateHandler, codeToString){
return {
restrict: 'E',
scope: {},
bindToController: true,
controllerAs: 'vm',
templateUrl: 'templates/js-shell.tpl.html',
- controller: function(ExploreCmd,LearnCmd){
+ controller: function(ExploreCmd, PlayCmd, LearnCmd){
var history = new Josh.History({ key: 'jsshell.history'});
this.shell = Josh.Shell({history: history});
@@ -58,8 +59,43 @@
}));
}
});
+
+ this.shell.setCommandHandler('play', {
+ exec: (cmd, args, done) => {
+ PlayCmd.setup(this.shell);
+ done(TemplateHandler.instructions({
+ title: `You can now play with UI components!`,
+ messages: [
+ `Use <code>component list</code> to list all the available component and <code>component {componentName}</code> to startusing it.`,
+ `An example command is <code>component xosTable</code>`
+ ]
+ }));
+ }
+ });
this.shell.activate();
+
+ this.componentScope = null;
+
+ $rootScope.$on('uiTutorial.attachScope', (e, scope) => {
+ this.componentScope = {
+ config: JSON.stringify(codeToString.toString(scope.config), null, 2),
+ data: JSON.stringify(codeToString.toString(scope.data), null, 2)
+ };
+ });
+
+ this.applyScope = (scope) => {
+
+ // let a = codeToString.toCode(scope.config);
+ // console.log(a);
+ const newScope = {
+ config: codeToString.toCode(scope.config),
+ data: eval(`(${scope.data})`)
+ };
+
+ $rootScope.$emit('uiTutorial.applyScope', newScope);
+ }
+
}
};
});
\ No newline at end of file
diff --git a/views/ngXosViews/UITutorial/src/js/playCmd.js b/views/ngXosViews/UITutorial/src/js/playCmd.js
new file mode 100644
index 0000000..0ed81c9
--- /dev/null
+++ b/views/ngXosViews/UITutorial/src/js/playCmd.js
@@ -0,0 +1,109 @@
+(function () {
+ 'use strict';
+ angular.module('xos.UITutorial')
+ .service('PlayCmd', function($compile, $rootScope, _, ErrorHandler){
+
+ // TODO investigate if we can load directives from an app
+ const components = [
+ {
+ name: 'xosTable',
+ template: '<xos-table config="config" data="data"></xos-table>',
+ scope: {
+ config: {
+ columns: [
+ {label: 'Name', prop: 'name'},
+ {label: 'Age', prop: 'age'}
+ ]
+ },
+ data: [
+ {name: 'Jhon', age: 23},
+ {name: 'Mike', age: 24}
+ ]
+ }
+ },
+ {
+ name: 'xosForm',
+ template: '<xos-form config="config" ng-model="data"></xos-form>',
+ scope: {
+ config: {
+ fields: {
+ name: {
+ type: 'text'
+ },
+ age: {
+ type: 'number'
+ }
+ },
+ actions: [
+ {
+ label: 'Print',
+ cb: (model) => {
+ console.log(model);
+ }
+ }
+ ]
+ },
+ data: {name: 'Jhon', age: 23}
+ }
+ }
+ ];
+
+ this.componentCompletion = (cmd, arg, line, done) => {
+ const componentsName = components.map(c => c.name);
+ return done(this.shell.bestMatch(arg, componentsName));
+ };
+
+ this.componentExec = (cmd, args, done) => {
+ const targetComponent = args[0];
+
+ if(!targetComponent){
+ return ErrorHandler.print(`Component "${targetComponent}" does not exists`, done);
+ }
+
+ this.attachComponent(targetComponent, done);
+ };
+
+ this.getComponentsDetails = (componentName, components) => {
+ return _.find(components, {name: componentName});
+ };
+
+ this.attachComponent = (targetComponent, done) => {
+ this.scope = $rootScope.$new();
+ targetComponent = this.getComponentsDetails(targetComponent, components);
+
+ angular.extend(this.scope, targetComponent.scope);
+
+ $rootScope.$emit('uiTutorial.attachScope', this.scope);
+
+ const directive = $compile(targetComponent.template)(this.scope);
+ const container = $('#directive-container');
+ container.html('');
+ container.append( directive );
+ done('Component added');
+ };
+
+ $rootScope.$on('uiTutorial.applyScope', (e, scope) => {
+ this.scope.config = scope.config;
+ this.scope.data = scope.data;
+ });
+
+ this.setup = (shell) => {
+ this.shell = shell;
+ shell.setCommandHandler('component', {
+ exec: this.componentExec,
+ completion: this.componentCompletion
+ });
+
+ // activate listener to enable/disable shell
+ $('.component-container').click((e) => {
+ this.shell.deactivate();
+ });
+
+ $('#shell-panel').click((e) => {
+ this.shell.activate();
+ });
+ };
+
+
+ });
+})();
\ No newline at end of file
diff --git a/views/ngXosViews/UITutorial/src/sass/main.scss b/views/ngXosViews/UITutorial/src/sass/main.scss
index f3b0496..a6e8003 100644
--- a/views/ngXosViews/UITutorial/src/sass/main.scss
+++ b/views/ngXosViews/UITutorial/src/sass/main.scss
@@ -19,6 +19,9 @@
#xosUITutorial {
width: 100%;
+
+ .ace_editor { height: 200px; }
+
js-shell {
display: block;
diff --git a/views/ngXosViews/UITutorial/src/templates/js-shell.tpl.html b/views/ngXosViews/UITutorial/src/templates/js-shell.tpl.html
index 8799fd4..aae18db 100644
--- a/views/ngXosViews/UITutorial/src/templates/js-shell.tpl.html
+++ b/views/ngXosViews/UITutorial/src/templates/js-shell.tpl.html
@@ -3,4 +3,29 @@
Type <code>help</code> or hit <code>TAB</code> for a list of commands.
</div>
<div id="shell-view"></div>
-</div>
\ No newline at end of file
+</div>
+
+<section class="component-container" ng-show="vm.componentScope">
+ <div class="row">
+ <div class="col-xs-6">
+ <label>Config:</label>
+ </div>
+ <div class="col-xs-6">
+ <label>data:</label>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-xs-6">
+ <div ng-model="vm.componentScope.config" ui-ace></div>
+ </div>
+ <div class="col-xs-6">
+ <div ng-model="vm.componentScope.data" ui-ace></div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-xs-12 text-right">
+ <a href="" ng-click="vm.applyScope(vm.componentScope)" class="btn btn-success">Apply Changes</a>
+ </div>
+ </div>
+ <div id="directive-container"></div>
+</section>
\ No newline at end of file