ngenerators 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|