ngenerators 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/README.md +3 -0
- data/install +3 -0
- data/lib/generators/ng.rb +1 -0
- data/lib/generators/ng/api_controller/USAGE +13 -0
- data/lib/generators/ng/api_controller/api_controller_generator.rb +29 -0
- data/lib/generators/ng/api_controller/templates/api_controller.rb +17 -0
- data/lib/generators/ng/api_controller/templates/index.json.jbuilder +4 -0
- data/lib/generators/ng/api_controller/templates/show.json.jbuilder +1 -0
- data/lib/generators/ng/base.rb +55 -0
- data/lib/generators/ng/directive/USAGE +9 -0
- data/lib/generators/ng/directive/directive_generator.rb +21 -0
- data/lib/generators/ng/directive/templates/directive.coffee +10 -0
- data/lib/generators/ng/directive/templates/directive.html +0 -0
- data/lib/generators/ng/form/USAGE +10 -0
- data/lib/generators/ng/form/form_generator.rb +27 -0
- data/lib/generators/ng/form/templates/form.html.erb +35 -0
- data/lib/generators/ng/form/templates/form_ctrl.coffee +6 -0
- data/lib/generators/ng/form/templates/spec.rb.erb +26 -0
- data/lib/generators/ng/index/USAGE +10 -0
- data/lib/generators/ng/index/index_generator.rb +33 -0
- data/lib/generators/ng/index/templates/index.html.erb +145 -0
- data/lib/generators/ng/index/templates/index_ctrl.coffee +19 -0
- data/lib/generators/ng/index/templates/spec.rb.erb +117 -0
- data/lib/generators/ng/resource/USAGE +8 -0
- data/lib/generators/ng/resource/resource_generator.rb +13 -0
- data/lib/generators/ng/resource/templates/resource.coffee +8 -0
- data/lib/generators/ng/show/USAGE +9 -0
- data/lib/generators/ng/show/show_generator.rb +23 -0
- data/lib/generators/ng/show/templates/show.html +20 -0
- data/lib/generators/ng/show/templates/show_ctrl.coffee +7 -0
- data/ngenerators.gemspec +18 -0
- metadata +91 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e3f3a9f583beaa3bacdc8c90aad48b955f8d3de7
|
4
|
+
data.tar.gz: 4dff109a532f6b5a8e113a5c7e0e6a6bd4ca5012
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 07fed6381de5cfacc70bc293b09371d510f02f3521f7bca0ce86079ea4b25c52c499b5420c4a033bc0d9ab8926449e781d20c0c1c5998134b2cbd4e18b767ef2
|
7
|
+
data.tar.gz: 4a2f734d2dad6eba336052c40d66585ee6d795a529d30cddc316affc3dcbf405c61546ac688f73ccdf1a549112148c93e069a2b4dcf56fcdcfec1e34eaf962c1
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.2
|
data/README.md
ADDED
data/install
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'generators/ng/base'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Description:
|
2
|
+
Generates Controller and Views for the API.
|
3
|
+
|
4
|
+
Example:
|
5
|
+
rails generate ng:api_controller client
|
6
|
+
|
7
|
+
This will create:
|
8
|
+
app/controllers/api/clients_controller.rb
|
9
|
+
app/views/api/clients/show.json.jbuilder
|
10
|
+
app/views/api/clients/index.json.jbuilder
|
11
|
+
|
12
|
+
Besides, it will update:
|
13
|
+
config/routes.rb
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'generators/ng'
|
2
|
+
|
3
|
+
module Ng
|
4
|
+
module Generators
|
5
|
+
class ApiControllerGenerator < Base
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
def controller
|
9
|
+
template 'api_controller.rb', "app/controllers/api/#{plural_name}_controller.rb"
|
10
|
+
template 'show.json.jbuilder', "app/views/api/#{plural_name}/show.json.jbuilder"
|
11
|
+
template 'index.json.jbuilder', "app/views/api/#{plural_name}/index.json.jbuilder"
|
12
|
+
end
|
13
|
+
|
14
|
+
def route
|
15
|
+
inject_into_file 'config/routes.rb', after: /namespace :api.+do\n/ do
|
16
|
+
" resources :#{plural_name}, only: [:show, :index]\n"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def symbolic_columns
|
23
|
+
klass.columns.map(&:name).map do |name|
|
24
|
+
":#{name}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Api
|
2
|
+
class <%= plural_name.camelize %>Controller < BaseController
|
3
|
+
<%- if options.model -%>
|
4
|
+
defaults resource_class: <%= options.model.try(:camelize) %>
|
5
|
+
|
6
|
+
<%- end -%>
|
7
|
+
<%- anothers = [] -%>
|
8
|
+
<%- klass.columns.each do |column| -%>
|
9
|
+
<%- if column.type == :date || column.type == :datetime -%>
|
10
|
+
has_scope :by_<%= column_name(column) %>, type: :hash, using: [:since, :until]
|
11
|
+
<%- else anothers << column end -%>
|
12
|
+
<%- end -%>
|
13
|
+
<%- if anothers.any? -%>
|
14
|
+
has_scope <%= anothers.map{ |col| ":by_#{column_name(col)}"}.join(', ') %>
|
15
|
+
<%- end -%>
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
json.(@<%= singular_name %>, <%= symbolic_columns.join(', ') %>)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Ng
|
2
|
+
module Generators
|
3
|
+
class Base < ::Rails::Generators::NamedBase
|
4
|
+
class_option :model, type: :string, default: nil,
|
5
|
+
description: "The name of the model when it differs from model_name"
|
6
|
+
|
7
|
+
protected
|
8
|
+
|
9
|
+
def ng_singular_name
|
10
|
+
singular_name.camelize(:lower)
|
11
|
+
end
|
12
|
+
|
13
|
+
def ng_plural_name
|
14
|
+
plural_name.camelize(:lower)
|
15
|
+
end
|
16
|
+
|
17
|
+
def klass
|
18
|
+
@klass ||= (options.model.try(:camelize) || class_name).constantize
|
19
|
+
end
|
20
|
+
|
21
|
+
def i18n_human
|
22
|
+
klass.model_name.human
|
23
|
+
end
|
24
|
+
|
25
|
+
def column_name(column)
|
26
|
+
column.name.gsub(/_id$/, '').gsub(/^id_/, '')
|
27
|
+
end
|
28
|
+
|
29
|
+
def i18n_column(column)
|
30
|
+
klass.human_attribute_name(column_name(column))
|
31
|
+
end
|
32
|
+
|
33
|
+
def column_is_association?(column)
|
34
|
+
!!association_for(column)
|
35
|
+
end
|
36
|
+
|
37
|
+
def association_for(column)
|
38
|
+
all_belongs_to.detect { |bt| bt.foreign_key.to_s == column.name }
|
39
|
+
end
|
40
|
+
|
41
|
+
def all_belongs_to
|
42
|
+
klass.reflect_on_all_associations.select { |a| a.macro == :belongs_to }
|
43
|
+
end
|
44
|
+
|
45
|
+
def input_type(column)
|
46
|
+
column.klass < Numeric ? 'number' : 'text'
|
47
|
+
end
|
48
|
+
|
49
|
+
def inject_ng_route(&block)
|
50
|
+
inject_into_file 'app/assets/javascripts/ng/routes.coffee',
|
51
|
+
after: "$stateProvider\n", &block
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'generators/ng'
|
2
|
+
|
3
|
+
module Ng
|
4
|
+
module Generators
|
5
|
+
class DirectiveGenerator < Base
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
class_option :template, type: :boolean, default: true, description: "Generate HTML template file"
|
8
|
+
|
9
|
+
def directive
|
10
|
+
template 'directive.coffee', "app/assets/javascripts/ng/directives/#{directive_name}.coffee"
|
11
|
+
template 'directive.html', "app/assets/templates/directives/#{directive_name}.html" if options.template?
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def directive_name
|
17
|
+
singular_name.gsub('_', '-')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
angular.module('<%= application_name %>')
|
2
|
+
|
3
|
+
.directive '<%= ng_singular_name %>', ->
|
4
|
+
restrict: 'AE'
|
5
|
+
<%- if options.template? -%>
|
6
|
+
templateUrl: "directives/<%= directive_name %>.html"
|
7
|
+
<%- else -%>
|
8
|
+
template: "<span></span>"
|
9
|
+
<%- end -%>
|
10
|
+
link: (scope) ->
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Description:
|
2
|
+
Generates Form HTML view to be used with AngularJS
|
3
|
+
|
4
|
+
Example:
|
5
|
+
rails generate ng:form client
|
6
|
+
|
7
|
+
This will create:
|
8
|
+
app/assets/templates/clients/form.html.erb
|
9
|
+
app/assets/javascripts/ng/controllers/client_form_ctrl.coffee
|
10
|
+
spec/features/client_show_spec.rb
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'generators/ng'
|
2
|
+
|
3
|
+
module Ng
|
4
|
+
module Generators
|
5
|
+
class FormGenerator < Base
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
def form
|
9
|
+
template 'form.html.erb', "app/assets/templates/#{plural_name}/form.html.erb"
|
10
|
+
template 'form_ctrl.coffee', "app/assets/javascripts/ng/controllers/#{singular_name}_form_ctrl.coffee"
|
11
|
+
end
|
12
|
+
|
13
|
+
def spec
|
14
|
+
template 'spec.rb.erb', "spec/features/#{singular_name}_show_spec.rb"
|
15
|
+
end
|
16
|
+
|
17
|
+
def route
|
18
|
+
inject_ng_route do
|
19
|
+
" .state '#{ng_singular_name}Form',\n"\
|
20
|
+
" controller: '#{class_name}FormCtrl'\n"\
|
21
|
+
" url: '/#{plural_name}/new'\n"\
|
22
|
+
" templateUrl: '#{plural_name}/form.html'\n\n"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<div class="page-header">
|
2
|
+
<h1 ng-if="! <%= ng_singular_name %>.id">Novo <%= i18n_human %></h1>
|
3
|
+
<h1 ng-if=" <%= ng_singular_name %>.id"><%= i18n_human %> {{ <%= ng_singular_name %>.id }}</h1>
|
4
|
+
</div>
|
5
|
+
|
6
|
+
<form class="form-horizontal" ng-submit="<%= ng_singular_name %>.save()" name="form" novalidate>
|
7
|
+
<div class="form-inputs">
|
8
|
+
<%- klass.columns.each do |column| -%>
|
9
|
+
<%%# <%= i18n_column(column).upcase %> %>
|
10
|
+
<my-input label="<%= i18n_column(column) %>" required="false" for="<%= singular_name %>_<%= column_name(column) %>" id="<%= column_name(column) %>">
|
11
|
+
<%- if column_is_association? column -%>
|
12
|
+
<!-- USE THIS TO TYPEAHEAD -->
|
13
|
+
<input autocomplete="off" autofocus="autofocus" name="<%= column_name(column) %>" required
|
14
|
+
class="form-control" id="<%= singular_name %>_<%= column_name(column) %>" ng-model="<%= ng_singular_name %>.<%= column_name(column) %>"
|
15
|
+
type="text" typeahead-min-length="3" typeahead-wait-ms="250"
|
16
|
+
typeahead="<%= column_name(column) %> as <%= column_name(column) %>.name for <%= column_name(column) %> in <%= column_name(column).pluralize %>($viewValue)">
|
17
|
+
<!-- END OF TYPEAHEAD -->
|
18
|
+
|
19
|
+
<!-- USE THIS TO SELECT -->
|
20
|
+
<select class="form-control" id="<%= singular_name %>_<%= column.name %>" ng-model="<%= ng_singular_name %>.<%= column.name %>"
|
21
|
+
ng-options="<%= column_name(column) %>.name for <%= column_name(column) %> in <%= column_name(column).pluralize %> track by <%= column_name(column) %>.id">
|
22
|
+
</select>
|
23
|
+
<!-- END OF SELECT -->
|
24
|
+
<%- else -%>
|
25
|
+
<input class="form-control" id="<%= singular_name %>_<%= column.name %>"
|
26
|
+
type="<%= input_type(column) %>" ng-model="<%= ng_singular_name %>.<%= column.name %>">
|
27
|
+
<%- end -%>
|
28
|
+
</my-input>
|
29
|
+
|
30
|
+
<%- end -%>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
<input class="btn btn-success" type="submit" value="Salvar" ng-disabled="form.$invalid">
|
34
|
+
<a class="btn btn-default" href="/">Cancelar</a>
|
35
|
+
</form>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "<%= class_name %>#form", js: true, type: :feature do
|
4
|
+
let(:user) { create(:user) }
|
5
|
+
let(:path) { "/<%= plural_name %>/new" }
|
6
|
+
|
7
|
+
before do
|
8
|
+
sign_in user
|
9
|
+
end
|
10
|
+
|
11
|
+
it "saves new records" do
|
12
|
+
visit path
|
13
|
+
|
14
|
+
<%- klass.columns.each do |column| -%>
|
15
|
+
fill_in '<%= i18n_column(column) %>', with: '1'
|
16
|
+
<%- end -%>
|
17
|
+
|
18
|
+
expect do
|
19
|
+
click_button 'Salvar'
|
20
|
+
end.to change(<%= class_name %>, :count).by(1)
|
21
|
+
<%= singular_name %> = <%= class_name %>.last
|
22
|
+
<%- klass.columns.each do |column| -%>
|
23
|
+
expect(<%= singular_name %>.<%= column.name %>).to eq '1'
|
24
|
+
<%- end -%>
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Description:
|
2
|
+
Generates Index HTML view to be used with AngularJS
|
3
|
+
|
4
|
+
Example:
|
5
|
+
rails generate ng:index client
|
6
|
+
|
7
|
+
This will create:
|
8
|
+
app/assets/templates/clients/index.html.erb
|
9
|
+
app/assets/javascripts/ng/controllers/clients_ctrl.coffee
|
10
|
+
spec/features/client_index_html_spec.rb
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'generators/ng'
|
2
|
+
|
3
|
+
module Ng
|
4
|
+
module Generators
|
5
|
+
class IndexGenerator < Base
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
def index
|
9
|
+
template 'index.html.erb', "app/assets/templates/#{plural_name}/index.html.erb"
|
10
|
+
template 'index_ctrl.coffee', "app/assets/javascripts/ng/controllers/#{plural_name}_ctrl.coffee"
|
11
|
+
end
|
12
|
+
|
13
|
+
def spec
|
14
|
+
template 'spec.rb.erb', "spec/features/#{singular_name}_index_html_spec.rb"
|
15
|
+
end
|
16
|
+
|
17
|
+
def route
|
18
|
+
inject_ng_route do
|
19
|
+
" .state '#{ng_plural_name}',\n"\
|
20
|
+
" controller: '#{plural_name.camelize}Ctrl'\n"\
|
21
|
+
" url: '/#{plural_name}'\n"\
|
22
|
+
" templateUrl: '#{plural_name}/index.html'\n\n"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def belongs_to_class_names
|
29
|
+
all_belongs_to.map(&:class_name)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
<div class="page-header"><h1><%= i18n_human.pluralize(I18n.locale) %></h1></div>
|
2
|
+
|
3
|
+
<form ng-submit="searcher.search()" class="form-horizontal">
|
4
|
+
<%- klass.columns.each do |column| -%>
|
5
|
+
<%- next if column.name == klass.primary_key.to_s -%>
|
6
|
+
<%%# <%= i18n_column(column).upcase %> %>
|
7
|
+
<div class="form-group">
|
8
|
+
<%- ################################################ -%>
|
9
|
+
<%- # DATE / TIME FILTER -%>
|
10
|
+
<%- if column.klass == Date || column.klass == Time -%>
|
11
|
+
<div class="col-md-6">
|
12
|
+
<div class="row">
|
13
|
+
<label class="col-md-4 col-sm-2 col-xs-12 control-label" for="created_at_since"><%= i18n_column(column) %></label>
|
14
|
+
<div class="col-md-4 col-sm-5 col-xs-6">
|
15
|
+
<p class="input-group">
|
16
|
+
<input type="text" class="form-control" is-open="<%= column.name %>_since.active"
|
17
|
+
ng-model="filters['by_<%= column.name %>[since]']" close-text="Fechar"
|
18
|
+
datepicker-popup="dd/MM/yyyy" ng-init="<%= column.name %>_since = {active: false}"
|
19
|
+
current-text="Hoje" clear-text="Limpar" id="<%= column.name %>_since"
|
20
|
+
title="<%= I18n.t(:since) %>" />
|
21
|
+
<span class="input-group-btn">
|
22
|
+
<button type="button" class="btn btn-default"
|
23
|
+
ng-click="$event.preventDefault(); $event.stopPropagation(); <%= column.name %>_since.active = !<%= column.name %>_since.active)">
|
24
|
+
<i class="glyphicon glyphicon-calendar"></i>
|
25
|
+
</button>
|
26
|
+
</span>
|
27
|
+
</p>
|
28
|
+
</div>
|
29
|
+
<div class="col-md-4 col-sm-5 col-xs-6">
|
30
|
+
<p class="input-group">
|
31
|
+
<input type="text" class="form-control" is-open="<%= column.name %>_until.active"
|
32
|
+
ng-model="filters['by_<%= column.name %>[until]']" close-text="Fechar"
|
33
|
+
datepicker-popup="dd/MM/yyyy" ng-init="<%= column.name %>_until = {active: false}"
|
34
|
+
current-text="Hoje" clear-text="Limpar" id="<%= column.name %>_until"
|
35
|
+
title="<%= I18n.t(:until) %>" />
|
36
|
+
<span class="input-group-btn">
|
37
|
+
<button type="button" class="btn btn-default"
|
38
|
+
ng-click="$event.preventDefault(); $event.stopPropagation(); <%= column.name %>_until.active = !<%= column.name %>_until.active)">
|
39
|
+
<i class="glyphicon glyphicon-calendar"></i>
|
40
|
+
</button>
|
41
|
+
</span>
|
42
|
+
</p>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
<%- else -%>
|
47
|
+
<label for="by_<%= column_name(column) %>" class="col-sm-2 control-label"><%= i18n_column(column) %></label>
|
48
|
+
<div class="col-sm-10" id="by_<%= column_name(column) %>_wrapper">
|
49
|
+
<%- ################################################ -%>
|
50
|
+
<%- # ASSOCIATION FILTER -%>
|
51
|
+
<%- if assoc = association_for(column) -%>
|
52
|
+
<!-- USE THIS TO TYPEAHEAD -->
|
53
|
+
<input autocomplete="off" autofocus="autofocus" name="<%= column_name(column) %>"
|
54
|
+
class="form-control" id="by_<%= column_name(column) %>" ng-model="filters.by_<%= column_name(column) %>"
|
55
|
+
type="text" typeahead-min-length="3" typeahead-wait-ms="250"
|
56
|
+
typeahead="<%= assoc.class_name.camelize(:lower) %> as <%= assoc.class_name.camelize(:lower) %>.description for <%= assoc.class_name.camelize(:lower) %> in <%= assoc.plural_name.camelize(:lower) %>($viewValue)">
|
57
|
+
<!-- END OF TYPEAHEAD -->
|
58
|
+
<!-- USE THIS TO SELECT -->
|
59
|
+
<select class="form-control" id="by_<%= column_name(column) %>" name="by_<%= column_name(column) %>" ng-model="filters.by_<%= column_name(column) %>"
|
60
|
+
ng-options="<%= assoc.class_name.camelize(:lower) %>.name for <%= assoc.class_name.camelize(:lower) %> in <%= assoc.plural_name.camelize(:lower) %> track by <%= assoc.class_name.camelize(:lower) %>.id">
|
61
|
+
<option value=""></option>
|
62
|
+
</select>
|
63
|
+
<!-- END OF SELECT -->
|
64
|
+
<%- ################################################ -%>
|
65
|
+
<%- # BOOLEAN FILTER -%>
|
66
|
+
<%- elsif column.type == :boolean -%>
|
67
|
+
<select class="form-control" id="by_<%= column_name(column) %>" name="by_<%= column_name(column) %>" ng-model="filters.by_<%= column_name(column) %>"
|
68
|
+
<option value=""></option>
|
69
|
+
<option value="true"><%= I18n.t(:yes) %></option>
|
70
|
+
<option value="false"><%= I18n.t(:no) %></option>
|
71
|
+
</select>
|
72
|
+
<%- ################################################ -%>
|
73
|
+
<%- else -%>
|
74
|
+
<input type="text" name="by_<%= column_name(column) %>" id="by_<%= column_name(column) %>" class="form-control"
|
75
|
+
ng-model="filters.by_<%= column_name(column) %>">
|
76
|
+
<%- end -%>
|
77
|
+
<%- ################################################ -%>
|
78
|
+
</div>
|
79
|
+
<%- end -%>
|
80
|
+
</div>
|
81
|
+
|
82
|
+
<%- end -%>
|
83
|
+
<div class="form-group">
|
84
|
+
<div class="col-sm-10 col-sm-offset-2">
|
85
|
+
<input class="btn btn-primary" name="commit" type="submit" value="Buscar">
|
86
|
+
<a class="btn-warning btn" ng-click="searcher.clear()" id="clear_filters" title="Limpar Filtros">
|
87
|
+
<span class="glyphicon glyphicon-remove"></span>
|
88
|
+
</a>
|
89
|
+
</div>
|
90
|
+
</div>
|
91
|
+
</form>
|
92
|
+
|
93
|
+
<small>
|
94
|
+
<table class="table table-striped table-hover table-bordered" id="<%= plural_name %>">
|
95
|
+
<tbody>
|
96
|
+
<tr>
|
97
|
+
<%- klass.columns.each do |column| -%>
|
98
|
+
<th<%= ' class="text-right"' if column.klass <= Numeric %>><%= i18n_column(column) %></th>
|
99
|
+
<%- end -%>
|
100
|
+
<th></th>
|
101
|
+
</tr>
|
102
|
+
<tr id="row_<%= singular_name %>_{{ <%= ng_singular_name %>.id }}" ng-repeat="<%= ng_singular_name %> in <%= ng_plural_name %>">
|
103
|
+
<td class="text-right">
|
104
|
+
<a ui-sref="<%= ng_singular_name %>({id: <%= ng_singular_name %>.id})" id="<%= singular_name %>_{{ <%= ng_singular_name %>.id }}_show">{{ <%= ng_singular_name %>.id }}</a></td>
|
105
|
+
<%- klass.columns.each do |column| -%>
|
106
|
+
<%- next if column.name == klass.primary_key.to_s -%>
|
107
|
+
<%- if column_is_association?(column) -%>
|
108
|
+
<td>{{ <%= ng_singular_name %>.<%= column_name(column).camelize(:lower) %>.name }}</td>
|
109
|
+
<%- elsif column.klass == Date || column.klass == Time -%>
|
110
|
+
<td>{{ <%= ng_singular_name %>.<%= column.name.camelize(:lower) %> | date }}</td>
|
111
|
+
<%- elsif column.klass <= Numeric -%>
|
112
|
+
<td class="text-right">{{ <%= ng_singular_name %>.<%= column.name.camelize(:lower) %> }}</td>
|
113
|
+
<%- else -%>
|
114
|
+
<td>{{ <%= ng_singular_name %>.<%= column.name.camelize(:lower) %> }}</td>
|
115
|
+
<%- end -%>
|
116
|
+
<%- end -%>
|
117
|
+
<td class="text-right">
|
118
|
+
<%%# VISUALIZAR %>
|
119
|
+
<a class="btn-info btn btn-xs" ui-sref="<%= ng_singular_name %>({ id: <%= ng_singular_name %>.id })"
|
120
|
+
id="show_<%= singular_name %>_{{ <%= ng_singular_name %>.id }}" title="Visualizar">
|
121
|
+
<span class="glyphicon glyphicon-search"></span></a>
|
122
|
+
|
123
|
+
<%%# ALTERAR %>
|
124
|
+
<a class="btn-warning btn btn-xs" ui-sref="edit<%= class_name %>({ id: <%= ng_singular_name %>.id })"
|
125
|
+
id="edit_<%= singular_name %>_{{ <%= ng_singular_name %>.id }}" title="Alterar" ng-show="<%= ng_singular_name %>.canUpdate">
|
126
|
+
<span class="glyphicon glyphicon-pencil"></span></a>
|
127
|
+
</td>
|
128
|
+
</tr>
|
129
|
+
</tbody>
|
130
|
+
</table>
|
131
|
+
</small>
|
132
|
+
|
133
|
+
<div class="row">
|
134
|
+
<div class="col-sm-6">
|
135
|
+
<pagination total-items="count" ng-model="filters.page"
|
136
|
+
direction-links="false" boundary-links="true" rotate="false"
|
137
|
+
items-per-page="<%= klass.default_per_page %>" ng-change="searcher.search()"
|
138
|
+
max-size="5" first-text="<%= I18n.t('views.pagination.first') %>" last-text="<%= I18n.t('views.pagination.last') %>"></pagination>
|
139
|
+
</div>
|
140
|
+
<div class="col-sm-6">
|
141
|
+
<p class="text-right">
|
142
|
+
Exibindo <b>{{ <%= ng_plural_name %>.length }}</b> de <b>{{ count }}</b>
|
143
|
+
</p>
|
144
|
+
</div>
|
145
|
+
</div>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
angular.module('<%= application_name %>')
|
2
|
+
|
3
|
+
.controller '<%= plural_name.camelize %>Ctrl', ['$scope', 'searcher', <%= ([class_name] + belongs_to_class_names).map{ |k| "'#{k}'"}.join(', ') %>
|
4
|
+
($scope, searcher, <%= ([class_name] + belongs_to_class_names).join(', ') %>) ->
|
5
|
+
$scope.searcher = searcher($scope, <%= class_name %>, '<%= ng_plural_name %>')
|
6
|
+
<%- klass.columns.each do |column| -%>
|
7
|
+
|
8
|
+
<%- if (assoc = association_for(column)) -%>
|
9
|
+
# FOR TYPEAHEAD
|
10
|
+
$scope.<%= assoc.plural_name %> = (filter) ->
|
11
|
+
<%= assoc.class_name %>.$get(<%= assoc.class_name %>.$url('ahead'), by_name: filter)
|
12
|
+
# END OF TYPEAHEAD
|
13
|
+
# FOR SELECT
|
14
|
+
<%= assoc.class_name %>.query().then (<%= assoc.plural_name.camelize(:lower) %>) ->
|
15
|
+
$scope.<%= assoc.plural_name.camelize(:lower) %> = <%= assoc.plural_name.camelize(:lower) %>
|
16
|
+
# END OF SELECT
|
17
|
+
<%- end -%>
|
18
|
+
<%- end -%>
|
19
|
+
]
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "<%= class_name %>#index", js: true do
|
4
|
+
let(:user) { create(:<%= singular_name %>_reader_user) }
|
5
|
+
let(:index) { '/<%= plural_name %>' }
|
6
|
+
|
7
|
+
before do
|
8
|
+
sign_in user
|
9
|
+
end
|
10
|
+
|
11
|
+
it "presents <%= plural_name.gsub('_', ' ') %>" do
|
12
|
+
<%= singular_name %>1 = create :<%= singular_name %>
|
13
|
+
<%= singular_name %>2 = create :<%= singular_name %>
|
14
|
+
|
15
|
+
visit index
|
16
|
+
|
17
|
+
expect(page).to have_content(<%= singular_name %>1.name)
|
18
|
+
expect(page).to have_content(<%= singular_name %>2.name)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "links to details" do
|
22
|
+
<%= singular_name %>1 = create :<%= singular_name %>
|
23
|
+
|
24
|
+
visit index
|
25
|
+
click_link "<%= singular_name %>_#{<%= singular_name %>1.id}_show"
|
26
|
+
|
27
|
+
expect(page ).to have_content('Detalhes')
|
28
|
+
expect(current_path).to eq "#{index}/#{<%= singular_name %>1.id}"
|
29
|
+
end
|
30
|
+
|
31
|
+
<%- klass.columns.each do |column| -%>
|
32
|
+
it "filters by <%= assoc.name.gsub('_', ' ') %>" do
|
33
|
+
<%- ################################################ -%>
|
34
|
+
<%- # TESTING ASSOCIATION FILTER -%>
|
35
|
+
<%- if assoc = association_for(column) -%>
|
36
|
+
<%= assoc.name %>1 = create :<%= assoc.class_name.underscore %>
|
37
|
+
<%= assoc.name %>2 = create :<%= assoc.class_name.underscore %>
|
38
|
+
<%= singular_name %>1 = create :<%= singular_name %>, <%= assoc.name %>: <%= assoc.name %>1
|
39
|
+
<%= singular_name %>2 = create :<%= singular_name %>, <%= assoc.name %>: <%= assoc.name %>2
|
40
|
+
|
41
|
+
visit index
|
42
|
+
# FOR TYPEAHEAD
|
43
|
+
fill_in_typeahead '<%= i18n_column(column) %>', <%= assoc.name %>1.name,
|
44
|
+
find('#by_<%= column_name(column) %>_wrapper')
|
45
|
+
# FOR SELECT
|
46
|
+
#select <%= assoc.name %>1.name, from: '<%= i18n_column(column) %>'
|
47
|
+
click_button 'Buscar'
|
48
|
+
|
49
|
+
expect(page).to_not have_content(<%= singular_name %>2.name)
|
50
|
+
expect(page).to have_content(<%= singular_name %>1.name)
|
51
|
+
<%- ################################################ -%>
|
52
|
+
<%- # TESTING INTEGER FILTER -%>
|
53
|
+
<%- elsif column.type == :integer -%>
|
54
|
+
<%= singular_name %>1 = create :<%= singular_name %>, <%= column.name %>: 1
|
55
|
+
<%= singular_name %>2 = create :<%= singular_name %>, <%= column.name %>: 2
|
56
|
+
|
57
|
+
visit index
|
58
|
+
fill_in '<%= i18n_column(column) %>', with: 1
|
59
|
+
click_button 'Buscar'
|
60
|
+
|
61
|
+
expect(page).to_not have_content(<%= singular_name %>2.name)
|
62
|
+
expect(page).to have_content(<%= singular_name %>1.name)
|
63
|
+
<%- ################################################ -%>
|
64
|
+
<%- # TESTING STRING FILTER -%>
|
65
|
+
<%- elsif column.type == :string -%>
|
66
|
+
<%= singular_name %>1 = create :<%= singular_name %>, <%= column.name %>: 'ABCD'
|
67
|
+
<%= singular_name %>2 = create :<%= singular_name %>, <%= column.name %>: 'EFGH'
|
68
|
+
|
69
|
+
visit index
|
70
|
+
fill_in '<%= i18n_column(column) %>', with: 'bc'
|
71
|
+
click_button 'Buscar'
|
72
|
+
|
73
|
+
expect(page).to_not have_content(<%= singular_name %>2.name)
|
74
|
+
expect(page).to have_content(<%= singular_name %>1.name)
|
75
|
+
<%- ################################################ -%>
|
76
|
+
<%- # TESTING BOOLEAN FILTER -%>
|
77
|
+
<%- elsif column.type == :boolean -%>
|
78
|
+
<%= singular_name %>1 = create :<%= singular_name %>, <%= column.name %>: false
|
79
|
+
<%= singular_name %>2 = create :<%= singular_name %>, <%= column.name %>: true
|
80
|
+
|
81
|
+
visit index
|
82
|
+
select '<%= I18n.t(:no) %>', from: '<%= i18n_column(column) %>'
|
83
|
+
click_button 'Buscar'
|
84
|
+
|
85
|
+
expect(page).to_not have_content(<%= singular_name %>2.name)
|
86
|
+
expect(page).to have_content(<%= singular_name %>1.name)
|
87
|
+
|
88
|
+
select '<%= I18n.t(:yes) %>', from: '<%= i18n_column(column) %>'
|
89
|
+
click_button 'Buscar'
|
90
|
+
|
91
|
+
expect(page).to_not have_content(<%= singular_name %>1.name)
|
92
|
+
expect(page).to have_content(<%= singular_name %>2.name)
|
93
|
+
<%- ################################################ -%>
|
94
|
+
<%- # TESTING DATE FILTER -%>
|
95
|
+
<%- elsif column.type == :date || column.type == :datetime -%>
|
96
|
+
<%= singular_name %>1 = create :<%= singular_name %>, <%= column.name %>: 1.day.ago
|
97
|
+
<%= singular_name %>2 = create :<%= singular_name %>, <%= column.name %>: Date.today
|
98
|
+
|
99
|
+
visit index
|
100
|
+
fill_in '<%= column.name %>_until', with: I18n.l(<%= singular_name %>1.<%= column.name %>)
|
101
|
+
click_button 'Buscar'
|
102
|
+
|
103
|
+
expect(page).to_not have_content(<%= singular_name %>2.name)
|
104
|
+
expect(page).to have_content(<%= singular_name %>1.name)
|
105
|
+
|
106
|
+
fill_in '<%= column.name %>_until', with: ''
|
107
|
+
fill_in '<%= column.name %>_since', with: I18n.l(<%= singular_name %>2.<%= column.name %>)
|
108
|
+
click_button 'Buscar'
|
109
|
+
|
110
|
+
expect(page).to_not have_content(<%= singular_name %>1.name)
|
111
|
+
expect(page).to have_content(<%= singular_name %>2.name)
|
112
|
+
<%- end -%>
|
113
|
+
<%- ################################################ -%>
|
114
|
+
end
|
115
|
+
|
116
|
+
<%- end -%>
|
117
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'generators/ng'
|
2
|
+
|
3
|
+
module Ng
|
4
|
+
module Generators
|
5
|
+
class ResourceGenerator < Base
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
def show
|
9
|
+
template 'resource.coffee', "app/assets/javascripts/ng/resources/#{singular_name}.coffee"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'generators/ng'
|
2
|
+
|
3
|
+
module Ng
|
4
|
+
module Generators
|
5
|
+
class ShowGenerator < Base
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
def show
|
9
|
+
template 'show.html', "app/assets/templates/#{plural_name}/show.html"
|
10
|
+
template 'show_ctrl.coffee', "app/assets/javascripts/ng/controllers/#{singular_name}_ctrl.coffee"
|
11
|
+
end
|
12
|
+
|
13
|
+
def route
|
14
|
+
inject_into_file 'app/assets/javascripts/ng/routes.coffee', after: "$stateProvider\n" do
|
15
|
+
" .state '#{ng_singular_name}',\n"\
|
16
|
+
" controller: '#{class_name}Ctrl'\n"\
|
17
|
+
" url: '/#{plural_name}/:id'\n"\
|
18
|
+
" templateUrl: '#{plural_name}/show.html'\n\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<div class="page-header">
|
2
|
+
<h1><%= i18n_human %> {{ <%= ng_singular_name %>.id }}</h1>
|
3
|
+
</div>
|
4
|
+
|
5
|
+
<dl class="dl-horizontal" id="<%= singular_name %>_{{ <%= ng_singular_name %>.id }}">
|
6
|
+
<%- klass.columns.each do |column| -%>
|
7
|
+
<span class="wrapper <%= singular_name %>_<%= column.name %>">
|
8
|
+
<dt><%= i18n_column(column) %></dt>
|
9
|
+
<dd class="content"><%- if (assoc = association_for(column)) -%>
|
10
|
+
{{ <%= ng_singular_name %>.<%= assoc.name.camelize(:lower) %>.name }}
|
11
|
+
<%- else -%>
|
12
|
+
{{ <%= ng_singular_name %>.<%= column.name.camelize(:lower) %> <%= ' | date' if column.type == :date || column.type == :datetime %> }}
|
13
|
+
<%- end -%></dd>
|
14
|
+
</span>
|
15
|
+
|
16
|
+
<%- end -%>
|
17
|
+
</dl>
|
18
|
+
|
19
|
+
<a class="btn btn-default" ui-sref="<%= ng_plural_name %>">
|
20
|
+
<span class="glyphicon glyphicon-arrow-left"></span> <%= I18n.t('helpers.links.back') %></a>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
angular.module('<%= application_name %>')
|
2
|
+
|
3
|
+
.controller '<%= class_name %>Ctrl', ['$scope', '$stateParams', '<%= class_name %>',
|
4
|
+
($scope, $stateParams, <%= class_name %>) ->
|
5
|
+
<%= class_name %>.get({ id: $stateParams.id }).then (<%= ng_singular_name %>) ->
|
6
|
+
$scope.<%= ng_singular_name %> = <%= ng_singular_name %>
|
7
|
+
]
|
data/ngenerators.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'ngenerators'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.date = '2014-10-02'
|
5
|
+
s.summary = "Rails Generators for AngularJS."
|
6
|
+
s.description = "This gem provides generators which generate AngularJS views,"\
|
7
|
+
" controllers and resources for AngularJS."
|
8
|
+
s.authors = ["Diego Aguir Selzlein"]
|
9
|
+
s.email = 'diegoselzlein@gmail.com'
|
10
|
+
|
11
|
+
s.files = `git ls-files`.split("\n")
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
|
14
|
+
s.homepage = 'https://github.com/nerde/ngenerators'
|
15
|
+
s.license = 'MIT'
|
16
|
+
|
17
|
+
s.add_dependency('i18n', '~> 0')
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ngenerators
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Diego Aguir Selzlein
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: i18n
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: This gem provides generators which generate AngularJS views, controllers
|
28
|
+
and resources for AngularJS.
|
29
|
+
email: diegoselzlein@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- ".rspec"
|
35
|
+
- ".ruby-version"
|
36
|
+
- README.md
|
37
|
+
- install
|
38
|
+
- lib/generators/ng.rb
|
39
|
+
- lib/generators/ng/api_controller/USAGE
|
40
|
+
- lib/generators/ng/api_controller/api_controller_generator.rb
|
41
|
+
- lib/generators/ng/api_controller/templates/api_controller.rb
|
42
|
+
- lib/generators/ng/api_controller/templates/index.json.jbuilder
|
43
|
+
- lib/generators/ng/api_controller/templates/show.json.jbuilder
|
44
|
+
- lib/generators/ng/base.rb
|
45
|
+
- lib/generators/ng/directive/USAGE
|
46
|
+
- lib/generators/ng/directive/directive_generator.rb
|
47
|
+
- lib/generators/ng/directive/templates/directive.coffee
|
48
|
+
- lib/generators/ng/directive/templates/directive.html
|
49
|
+
- lib/generators/ng/form/USAGE
|
50
|
+
- lib/generators/ng/form/form_generator.rb
|
51
|
+
- lib/generators/ng/form/templates/form.html.erb
|
52
|
+
- lib/generators/ng/form/templates/form_ctrl.coffee
|
53
|
+
- lib/generators/ng/form/templates/spec.rb.erb
|
54
|
+
- lib/generators/ng/index/USAGE
|
55
|
+
- lib/generators/ng/index/index_generator.rb
|
56
|
+
- lib/generators/ng/index/templates/index.html.erb
|
57
|
+
- lib/generators/ng/index/templates/index_ctrl.coffee
|
58
|
+
- lib/generators/ng/index/templates/spec.rb.erb
|
59
|
+
- lib/generators/ng/resource/USAGE
|
60
|
+
- lib/generators/ng/resource/resource_generator.rb
|
61
|
+
- lib/generators/ng/resource/templates/resource.coffee
|
62
|
+
- lib/generators/ng/show/USAGE
|
63
|
+
- lib/generators/ng/show/show_generator.rb
|
64
|
+
- lib/generators/ng/show/templates/show.html
|
65
|
+
- lib/generators/ng/show/templates/show_ctrl.coffee
|
66
|
+
- ngenerators.gemspec
|
67
|
+
homepage: https://github.com/nerde/ngenerators
|
68
|
+
licenses:
|
69
|
+
- MIT
|
70
|
+
metadata: {}
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 2.2.2
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: Rails Generators for AngularJS.
|
91
|
+
test_files: []
|