Skip to content

Commit 3c94692

Browse files
committed
wip(generator-widget): generate basic widget-component
1 parent a8957f0 commit 3c94692

22 files changed

+372
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# http://editorconfig.org
2+
root = true
3+
4+
[*]
5+
indent_style = space
6+
indent_size = 2
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text=auto
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

generators/generator-widget/.jshintrc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"node": true,
3+
"esnext": true,
4+
"bitwise": true,
5+
"camelcase": true,
6+
"curly": true,
7+
"eqeqeq": true,
8+
"immed": true,
9+
"indent": 2,
10+
"latedef": true,
11+
"newcap": true,
12+
"noarg": true,
13+
"quotmark": "single",
14+
"undef": true,
15+
"unused": true,
16+
"strict": true
17+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
sudo: false
2+
language: node_js
3+
node_js:
4+
- 'iojs'
5+
- '0.12'
6+
- '0.10'
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"generator-generator": {
3+
"structure": "nested"
4+
}
5+
}

generators/generator-widget/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# generator-widget
2+
---
3+
4+
Generator for building impac-angular widget components.
5+
6+
### Todo
7+
---
8+
9+
- read how all widget directives are formed and put together generic scenearios
10+
- prompt chart types
11+
- generate different chart formatter functions
12+
- generate different chart html templates
13+
- generate standard widget specific methods based on prompted chart type
14+
- prompt controls for widget specific alterations, e.g:
15+
- expandable-list with 2 column comparison or single column.
16+
- prompt selection of widgets-settings
17+
18+
### Notes
19+
---
20+
21+
##### generating chart formatter functions and widget specific methods
22+
Can I inject javascript from different file into widget-component.directive?
23+
Would be cool to be able to build files structures based on widget chart types, and then based on the widget prompt selected & a few other prompts, build out all generic methods and variable settings in the directive controller.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
'use strict';
2+
var yeoman = require('yeoman-generator');
3+
var chalk = require('chalk');
4+
var yosay = require('yosay');
5+
var _ = require('lodash');
6+
var inquirer = require('inquirer');
7+
var ejs = require('ejs');
8+
var beautify = require('js-beautify');
9+
var fs = require('fs');
10+
11+
module.exports = yeoman.generators.Base.extend({
12+
initializing: function () {
13+
this.charts = [
14+
new inquirer.Separator(),
15+
{ id: 1, name: 'Pie Chart', value: 'pie', type: 'graph' },
16+
{ id: 2, name: 'Line Chart', value: 'line', type: 'graph' },
17+
new inquirer.Separator(),
18+
{ id: 3, name: 'Blank - content only / custom', value: 'blank' },
19+
new inquirer.Separator(),
20+
];
21+
this.chartAddOns = [
22+
{ value: 'legend', name: 'Legend', checked: false }
23+
];
24+
this.buildOptionPath = function (options) {
25+
var templatePath = this.templatePath();
26+
return _.map(options, function (option) {
27+
return templatePath + '/widget-component/partials/_' + option + '.html';
28+
});
29+
};
30+
},
31+
prompting: function () {
32+
var done = this.async();
33+
// Have Yeoman greet the user.
34+
this.log(yosay(
35+
chalk.green('Welcome to the Impac! widget generator!')
36+
));
37+
38+
var charts = this.charts;
39+
var chartAddOns = this.chartAddOns;
40+
var prompts = [
41+
{
42+
type: 'list',
43+
name: 'chartName',
44+
message: 'Select which chart/content type you would like to build.',
45+
choices: charts
46+
},
47+
{
48+
when: function (prop) {
49+
return _.find(charts, { value: prop.chartName }).type === 'graph';
50+
},
51+
type: 'checkbox',
52+
name: 'chartAddOns',
53+
message: 'Which chart add-ons would you like to include',
54+
choices: chartAddOns
55+
}
56+
];
57+
58+
this.prompt(prompts, function (props) {
59+
// Array of selections made after prompting.
60+
this.props = props;
61+
this.chartType = _.find(charts, { value: props.chartName }).type;
62+
63+
done();
64+
}.bind(this));
65+
},
66+
67+
writing: {
68+
// Write task for generating the new widgets html template file.
69+
widgetTemplate: function () {
70+
var data, html, template;
71+
72+
data = {
73+
chartContainerClass: '',
74+
options: this.buildOptionPath(_.flatten(_.map(this.props, function (prop) {
75+
return prop;
76+
})))
77+
};
78+
if (this.chartType === 'graph') {
79+
data.chartContainerClass = 'chart-container';
80+
}
81+
82+
html = this.fs.read(this.templatePath('widget-component/widget-component.tmpl.html'));
83+
84+
template = ejs.render(html, data, {filename: this.templatePath('widget-component')});
85+
86+
template = beautify.html(template, { indent_size: 2 });
87+
88+
this.fs.write(
89+
this.destinationPath('components/widgets/widget-component.tmpl.html'),
90+
template
91+
);
92+
},
93+
// Write task for generating the new widgets directive component file.
94+
widgetDirective: function () {
95+
var html, template, data, buffer, path, settingsPromises;
96+
97+
settingsPromises = [];
98+
if (this.chartType === 'graph') {
99+
settingsPromises.push('chart');
100+
}
101+
data = {
102+
settingsPromises: settingsPromises
103+
};
104+
105+
html = this.fs.read(this.templatePath('widget-component/widget-component.directive.coffee'));
106+
template = ejs.render(html, {data: data}, {filename: this.templatePath('widget-component')});
107+
108+
// TODO: move to method.
109+
// - warning when before overwriting.
110+
// - nice logs
111+
// - doc the purpose of not using this.fs for I/O.
112+
buffer = new Buffer(template);
113+
path = this.destinationPath('components/widgets/widget-component.directive.coffee');
114+
fs.open(path, 'w', function(err, fd) {
115+
if (err) throw 'error opening file: ' + err;
116+
117+
fs.write(fd, buffer, 0, buffer.length, null, function(err) {
118+
if (err) throw 'error writing file: ' + err;
119+
120+
fs.close(fd, function() {
121+
console.log('file written');
122+
});
123+
});
124+
});
125+
}
126+
},
127+
128+
install: function () {
129+
this.installDependencies();
130+
}
131+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "package",
3+
"version": "0.0.0",
4+
"dependencies": {}
5+
}
6+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "package",
3+
"version": "0.0.0",
4+
"dependencies": {}
5+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# http://editorconfig.org
2+
root = true
3+
4+
[*]
5+
indent_style = space
6+
indent_size = 2
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"node": true,
3+
"esnext": true,
4+
"bitwise": true,
5+
"camelcase": true,
6+
"curly": true,
7+
"eqeqeq": true,
8+
"immed": true,
9+
"indent": 2,
10+
"latedef": true,
11+
"newcap": true,
12+
"noarg": true,
13+
"quotmark": "single",
14+
"undef": true,
15+
"unused": true,
16+
"strict": true
17+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<p>Add your widget content here.</p>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div class="legend">
2+
<!-- chart data here -->
3+
</div>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
<div impac-chart draw-trigger="::drawTrigger.promise" deferred="::chartDeferred"></div>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div setting-organizations parent-widget="widget" class="part" deferred="::orgDeferred" />
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
<div impac-chart draw-trigger="::drawTrigger.promise" deferred="::chartDeferred"></div>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module = angular.module('impac.components.widgets.accounts-class-balance-details', [])
2+
module.controller('WidgetAccountsClassBalanceDetailsCtrl', ($scope, $q, ChartFormatterSvc) ->
3+
4+
w = $scope.widget
5+
6+
# Define settings
7+
# --------------------------------------
8+
<%_ data.settingsPromises.forEach(function (name) { _%>
9+
$scope.<%= name + 'Deferred' %> = $q.defer();
10+
<%_ }) _%>
11+
12+
settingsPromises = [
13+
<%_ data.settingsPromises.forEach(function (name) { _%>
14+
$scope.<%= name + 'Deferred' %>.promise,
15+
<%_ }) _%>
16+
]
17+
18+
# Widget specific methods
19+
# --------------------------------------
20+
w.initContext = ->
21+
$scope.isDataFound = w.content?
22+
23+
# Chart formating function
24+
# --------------------------------------
25+
26+
# Widget is ready: can trigger the "wait for settings to be ready"
27+
# --------------------------------------
28+
$scope.widgetDeferred.resolve(settingsPromises)
29+
)
30+
module.directive('widgetAccountsClassBalanceDetails', ->
31+
return {
32+
restrict: 'A',
33+
controller: 'WidgetAccountsClassBalanceDetailsCtrl'
34+
}
35+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.analytics .widget-item .content.widget-component {
2+
3+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<!--
2+
Template generated by Impac! Widget Generator!
3+
-->
4+
<div widget-widget-component>
5+
<!-- Settings Panel -->
6+
<div ng-show="widget.isEditMode" class="edit">
7+
<h4>Widget settings</h4>
8+
9+
<!-- inject:widgets-settings -->
10+
<!-- endinject -->
11+
12+
<!-- Buttons displayed on the lower -->
13+
<div class="bottom-buttons" align="right">
14+
<button class="btn btn-default" ng-click="initSettings()">Cancel</button>
15+
<button class="btn btn-warning" ng-click="updateSettings()">Save</button>
16+
</div>
17+
</div>
18+
19+
<!-- Content Panel -->
20+
<div ng-hide="widget.isEditMode">
21+
<!-- Data found -->
22+
<div ng-show="(isDataFound==true)" class="<%= chartContainerClass %>">
23+
<%_ options.forEach(function(option){ _%>
24+
<%- include(option); %>
25+
<%_ }); _%>
26+
</div>
27+
28+
<!-- No data found -->
29+
<div ng-show="(isDataFound==false)" common-data-not-found on-display-alerts="onDisplayAlerts()" widget-engine="::widget.category" />
30+
</div>
31+
</div>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "generator-widget",
3+
"version": "0.0.0",
4+
"description": "Yeoman generator",
5+
"license": "MIT",
6+
"main": "app/index.js",
7+
"repository": "xaun/generator-widget",
8+
"author": {
9+
"name": "Xaun Lopez",
10+
"email": "[email protected]",
11+
"url": "https://github.com/xaun"
12+
},
13+
"scripts": {
14+
"test": "mocha"
15+
},
16+
"files": [
17+
"generators"
18+
],
19+
"keywords": [
20+
"yeoman-generator"
21+
],
22+
"dependencies": {
23+
"chalk": "^1.0.0",
24+
"ect": "^0.5.9",
25+
"ejs": "~2.4.1",
26+
"js-beautify": "^1.6.2",
27+
"lodash": "^4.6.1",
28+
"yeoman-generator": "^0.20.2",
29+
"yosay": "^1.0.2"
30+
},
31+
"devDependencies": {
32+
"mocha": "*"
33+
}
34+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
var path = require('path');
4+
var assert = require('yeoman-generator').assert;
5+
var helpers = require('yeoman-generator').test;
6+
var os = require('os');
7+
8+
describe('widget:app', function () {
9+
before(function (done) {
10+
helpers.run(path.join(__dirname, '../generators/app'))
11+
.withOptions({ skipInstall: true })
12+
.withPrompts({ someOption: true })
13+
.on('end', done);
14+
});
15+
16+
it('creates files', function () {
17+
assert.file([
18+
'bower.json',
19+
'package.json',
20+
'.editorconfig',
21+
'.jshintrc'
22+
]);
23+
});
24+
});

0 commit comments

Comments
 (0)