dashstrap 0.1.0
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/.gitignore +19 -0
- data/.yardopts +1 -0
- data/Gemfile +8 -0
- data/LICENSE +339 -0
- data/README.md +40 -0
- data/Rakefile +13 -0
- data/TODO.org +3 -0
- data/app/assets/fonts/BYekan.eot +0 -0
- data/app/assets/fonts/BYekan.ttf +0 -0
- data/app/assets/fonts/BYekan.woff +0 -0
- data/app/assets/javascripts/dashstrap/application.js +2 -0
- data/app/assets/javascripts/dashstrap/functions.js +27 -0
- data/app/assets/javascripts/dashstrap/locales/translations.fa.js +5 -0
- data/app/assets/javascripts/dashstrap/modules/init.js +1 -0
- data/app/assets/javascripts/dashstrap/modules/list-view.js +376 -0
- data/app/assets/javascripts/dashstrap/modules/modules.js +79 -0
- data/app/assets/javascripts/dashstrap/modules/navigation.js +24 -0
- data/app/assets/javascripts/locales/translations.fa.js +5 -0
- data/app/assets/locales/templates.pot +92 -0
- data/app/assets/locales/translate.fa.pot +93 -0
- data/app/assets/stylesheets/dashstrap/ltr/application.css +17 -0
- data/app/assets/stylesheets/dashstrap/ltr/ltr.scss +15 -0
- data/app/assets/stylesheets/dashstrap/main.css.scss +63 -0
- data/app/assets/stylesheets/dashstrap/rtl/#application.css# +4 -0
- data/app/assets/stylesheets/dashstrap/rtl/application.css +18 -0
- data/app/assets/stylesheets/dashstrap/rtl/rtl.scss +38 -0
- data/app/assets/stylesheets/dashstrap/share.scss +7 -0
- data/app/assets/stylesheets/faalis/ltr/application.css +0 -0
- data/app/assets/stylesheets/faalis/rtl/application.css +0 -0
- data/app/assets/stylesheets/simple/ltr/application.css +4 -0
- data/app/assets/stylesheets/simple/rtl/application.css +5 -0
- data/app/assets/stylesheets/simple/rtl/rtl.scss +16 -0
- data/app/assets/stylesheets/simple/share.scss +11 -0
- data/app/views/angular/auth/groups/details.html +21 -0
- data/app/views/angular/auth/groups/index.html.slim +2 -0
- data/app/views/angular/auth/groups/new.html.slim +44 -0
- data/app/views/angular/auth/index.html +30 -0
- data/app/views/angular/auth/profile/edit.html +54 -0
- data/app/views/angular/auth/users/details.html +28 -0
- data/app/views/angular/auth/users/index.html +6 -0
- data/app/views/angular/auth/users/new.html +57 -0
- data/app/views/angular/fields/accordion/accordion-group.html +10 -0
- data/app/views/angular/fields/accordion/accordion.html +1 -0
- data/app/views/angular/fields/alert/alert.html +7 -0
- data/app/views/angular/fields/boolean/boolean.html +4 -0
- data/app/views/angular/fields/carousel/carousel.html +8 -0
- data/app/views/angular/fields/carousel/slide.html +7 -0
- data/app/views/angular/fields/control-combo/control-list.html +19 -0
- data/app/views/angular/fields/datepicker/datepicker.html +5 -0
- data/app/views/angular/fields/datepicker/day.html +21 -0
- data/app/views/angular/fields/datepicker/month.html +16 -0
- data/app/views/angular/fields/datepicker/popup.html +10 -0
- data/app/views/angular/fields/datepicker/year.html +16 -0
- data/app/views/angular/fields/datetime/datetime.html +10 -0
- data/app/views/angular/fields/datetime/time.html +25 -0
- data/app/views/angular/fields/float/float.html +4 -0
- data/app/views/angular/fields/image/image.html +1 -0
- data/app/views/angular/fields/integer/integer.html +4 -0
- data/app/views/angular/fields/modal/backdrop.html +4 -0
- data/app/views/angular/fields/modal/window.html +3 -0
- data/app/views/angular/fields/pagination/pager.html +4 -0
- data/app/views/angular/fields/pagination/pagination.html +7 -0
- data/app/views/angular/fields/popover/popover.html +8 -0
- data/app/views/angular/fields/progressbar/bar.html +1 -0
- data/app/views/angular/fields/progressbar/progress.html +1 -0
- data/app/views/angular/fields/progressbar/progressbar.html +3 -0
- data/app/views/angular/fields/rating/rating.html +5 -0
- data/app/views/angular/fields/relation/relation.html +43 -0
- data/app/views/angular/fields/string/string.html +22 -0
- data/app/views/angular/fields/tabs/tab.html +3 -0
- data/app/views/angular/fields/tabs/tabset.html +10 -0
- data/app/views/angular/fields/tag/tag.html +3 -0
- data/app/views/angular/fields/text/text.html +4 -0
- data/app/views/angular/fields/timepicker/timepicker.html +26 -0
- data/app/views/angular/fields/tooltip/tooltip-html-unsafe-popup.html +4 -0
- data/app/views/angular/fields/tooltip/tooltip-popup.html +4 -0
- data/app/views/angular/fields/typeahead/typeahead-match.html +1 -0
- data/app/views/angular/fields/typeahead/typeahead-popup.html +5 -0
- data/app/views/angular/index.html +448 -0
- data/app/views/angular/list-view/index.html +161 -0
- data/app/views/angular/modules.html +46 -0
- data/app/views/angular/nav.html.erb +273 -0
- data/app/views/dashstrap/.keep +0 -0
- data/app/views/devise/registrations/edit.html.erb +29 -0
- data/app/views/devise/registrations/new.html.erb +36 -0
- data/app/views/devise/sessions/new.html.erb +33 -0
- data/app/views/devise/shared/_links.erb +19 -0
- data/app/views/devise/shared/_omni_link.erb +15 -0
- data/app/views/faalis/dashboard/index.html.erb +44 -0
- data/app/views/faalis/dashboard/login_required_page.html.erb +5 -0
- data/app/views/layouts/dashstrap/.keep +0 -0
- data/app/views/layouts/faalis/application.html.erb +83 -0
- data/app/views/layouts/faalis/dashboard.html.erb +26 -0
- data/app/views/layouts/faalis/simple.html.erb +22 -0
- data/dashstrap.gemspec +39 -0
- data/lib/dashstrap/engine.rb +29 -0
- data/lib/dashstrap/version.rb +3 -0
- data/lib/dashstrap.rb +4 -0
- data/lib/generators/dashstrap/install_generator.rb +14 -0
- data/lib/generators/templates/js/list_view/README +31 -0
- data/lib/generators/templates/js/list_view/details.html.erb +25 -0
- data/lib/generators/templates/js/list_view/index.html.erb +89 -0
- data/lib/generators/templates/js/list_view/module.js.erb +10 -0
- data/lib/generators/templates/js/list_view/new.html.erb +81 -0
- data/lib/generators/templates/js/list_view/partials/add_controller.js.erb +103 -0
- data/lib/generators/templates/js/list_view/partials/config.js.erb +20 -0
- data/lib/generators/templates/js/list_view/partials/index_controller.js.erb +199 -0
- data/lib/generators/templates/js/list_view/partials/menu.js.erb +6 -0
- data/lib/generators/templates/stylesheets/application.css +13 -0
- data/lib/generators/templates/stylesheets/dashboard/ltr/application.css +1 -0
- data/lib/generators/templates/stylesheets/dashboard/rtl/application.css +1 -0
- data/lib/generators/templates/stylesheets/ltr/application.css +6 -0
- data/lib/generators/templates/stylesheets/rtl/application.css +4 -0
- data/lib/tasks/.keep +0 -0
- data/lib/tasks/build.rake +15 -0
- data/lib/tasks/grunt/Gruntfile.js +30 -0
- data/vendor/assets/fonts/FontAwesome.otf +0 -0
- data/vendor/assets/fonts/fontawesome-webfont.eot +0 -0
- data/vendor/assets/fonts/fontawesome-webfont.svg +414 -0
- data/vendor/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/vendor/assets/fonts/fontawesome-webfont.woff +0 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.eot +0 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.svg +229 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.woff +0 -0
- data/vendor/assets/fonts/ionicons.eot +0 -0
- data/vendor/assets/fonts/ionicons.svg +1623 -0
- data/vendor/assets/fonts/ionicons.ttf +0 -0
- data/vendor/assets/fonts/ionicons.woff +0 -0
- data/vendor/assets/javascripts/.keep +0 -0
- data/vendor/assets/javascripts/AdminLTE/app.js +1037 -0
- data/vendor/assets/javascripts/AdminLTE/dashboard.js +254 -0
- data/vendor/assets/javascripts/bootstrap.js +2114 -0
- data/vendor/assets/javascripts/ui-bootstrap.js +3799 -0
- data/vendor/assets/stylesheets/.keep +0 -0
- data/vendor/assets/stylesheets/AdminLTE.css +3024 -0
- data/vendor/assets/stylesheets/bootstrap.css +7118 -0
- data/vendor/assets/stylesheets/rtl/AdminLTE.css +3032 -0
- data/vendor/assets/stylesheets/rtl/bootstrap-rtl.css +442 -0
- data/vendor/assets/stylesheets/rtl/bootstrap.css +6239 -0
- metadata +366 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'faalis/extension'
|
|
2
|
+
require 'jquery-ui-rails'
|
|
3
|
+
require 'font-awesome-rails'
|
|
4
|
+
require 'select2-rails'
|
|
5
|
+
|
|
6
|
+
module Dashstrap
|
|
7
|
+
class TemplateEngine < ::Rails::Engine
|
|
8
|
+
|
|
9
|
+
include Faalis::Extension::Base
|
|
10
|
+
|
|
11
|
+
def self.register_extension(name, klass)
|
|
12
|
+
Faalis::Extension.extensions[name] = klass
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.override_generator_templates(template_path)
|
|
16
|
+
send(:define_singleton_method, 'generator_templates_path') do
|
|
17
|
+
template_path
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
register_extension 'dashstrap', self
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
override_generator_templates File.expand_path('../../generators/templates', __FILE__)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
require 'dashstrap/version'
|
data/lib/dashstrap.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Dashstrap
|
|
2
|
+
module Generators
|
|
3
|
+
# Generator responsible for `install` generator
|
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
|
5
|
+
source_root File.expand_path('../../templates', __FILE__)
|
|
6
|
+
|
|
7
|
+
desc 'Copy all the necessary files to use Dashstrap'
|
|
8
|
+
|
|
9
|
+
def copy_scss_manifest
|
|
10
|
+
directory 'stylesheets', 'app/assets/stylesheets'
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
==================================================
|
|
2
|
+
Steps to installation:
|
|
3
|
+
|
|
4
|
+
0. You have to have a working model to use this scaffold. So create
|
|
5
|
+
your model and setup validations, relations and other stuff.
|
|
6
|
+
|
|
7
|
+
1. Add resource to routes.rb for example in case of `car` scaffold do:
|
|
8
|
+
|
|
9
|
+
namespace :api, :defaults => {:format => :json} do
|
|
10
|
+
namespace :v1 do
|
|
11
|
+
resources :cars, :except => [:new]
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
2. The Angularjs module of your resource should be added as an dependency
|
|
16
|
+
to another Angularjs module. Add it by hand or if you want to view module
|
|
17
|
+
in dashboard's main page add your resource to `config/initializers/faalis.rb`
|
|
18
|
+
like this:
|
|
19
|
+
|
|
20
|
+
config.dashboard_modules = {
|
|
21
|
+
:car => {
|
|
22
|
+
:icon => "fa fa-car",
|
|
23
|
+
:sidemenu => true,
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
3. Make sure that you have `api_controller.rb` in your `app/controllers` with this content:
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class APIController < Faalis::APIController
|
|
31
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<div class="row">
|
|
2
|
+
<div class="col-sm-12 col-md-8">
|
|
3
|
+
|
|
4
|
+
<div class="details">
|
|
5
|
+
<% fields.each do |f, field_type| %>
|
|
6
|
+
<dl>
|
|
7
|
+
<% case field_type
|
|
8
|
+
when "belongs_to" %> <dt translate><%= f.capitalize %> :</dt> <dd clas="detail field value">{{object.<%= f %>.name}}</dd>
|
|
9
|
+
<% when "has_many" %><dl>
|
|
10
|
+
<dt translate><%= f.capitalize %> :</dt>
|
|
11
|
+
<ul>
|
|
12
|
+
<li ng-repeat="item in object.<%= f %>"> {{ item.name }}</li>
|
|
13
|
+
</ul>
|
|
14
|
+
</dl>
|
|
15
|
+
<% else %><dt translate><%= f.capitalize %> :</dt> <dd clas="detail field value">{{object.<%= f %>}}</dd>
|
|
16
|
+
<% end %></dl>
|
|
17
|
+
<% end %>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<div class="col-sm-12 col-md-4">
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<% unless no_filter? %>
|
|
2
|
+
<filter config="filter_config" result="<%= resource.pluralize.underscore %>"></filter>
|
|
3
|
+
<% end %>
|
|
4
|
+
<% unless no_bulk? %>
|
|
5
|
+
<div class="row">
|
|
6
|
+
<div class="col-sm-12">
|
|
7
|
+
<div ng-if="bulk_edit" class="fade_anim box box-info">
|
|
8
|
+
<form id="bulk_form">
|
|
9
|
+
<div class="bod-header">
|
|
10
|
+
<h2 translate>Bulk Edit</h2>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="box-body">
|
|
13
|
+
<div class="row">
|
|
14
|
+
<div class="col-sm-6 columns">
|
|
15
|
+
<div class="form-group">
|
|
16
|
+
<label for="field_name" translate>Field Name:</label>
|
|
17
|
+
|
|
18
|
+
<select id="field_name" ng-model="field_name" ng-change="field_name_change()" class="form-control">
|
|
19
|
+
<option value="0" selected translate>-- Select a field --</option>
|
|
20
|
+
<option ng-repeat="field in fields" value="{{ field.name }}" data-type="{{ field.type }}" data-to="{{ field.to }}"><span translate>{{ field.title }}</span></option>
|
|
21
|
+
</select>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="col-sm-6 columns">
|
|
26
|
+
<div class="form-group">
|
|
27
|
+
<label for="field_value" translate>Field Value:</label>
|
|
28
|
+
<div id="value_field">
|
|
29
|
+
<input id="field_value" ng-model="field_value" type="text" ng-if="current_field.type == 'string' || current_field.type == 'integer'" class="form-control">
|
|
30
|
+
<textarea id="field_value" class="form-control" ng-model="field_value" ng-if="current_field.type == 'text'"></textarea>
|
|
31
|
+
|
|
32
|
+
<select id="field_value" ng-model="field_value" class="form-control" ng-if="current_field.type == 'belongs_to'">
|
|
33
|
+
<option ng-repeat="item in cache[current_field.name]" value="{{ item.id }}">{{ item.name }}</option>
|
|
34
|
+
</select>
|
|
35
|
+
<select id="field_value" ng-model="field_value" class="form-control" ng-if="current_field.type == 'has_many'" multiple>
|
|
36
|
+
<option ng-repeat="item in cache[current_field.name]" value="{{ item.id }}">{{ item.name }}</option>
|
|
37
|
+
</select>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
<div class="row progressbar-container" ng-if="view_progressbar">
|
|
43
|
+
<div class="col-sm-12 columns">
|
|
44
|
+
|
|
45
|
+
<div class="progressbar">
|
|
46
|
+
<div class="progress xs progress-striped">
|
|
47
|
+
<div id="request_filler" class="filler progress-bar progress-bar-warning" role="progressbar" aria-valuenow="{{ rfiller }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ rfiller }}">
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<div class="progress xs progress-striped">
|
|
52
|
+
<div id="request_filler" class="filler progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{ sfiller }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ sfiller }}">
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div class="row">
|
|
61
|
+
<div class="col-sm-3 columns pull-right text-right">
|
|
62
|
+
<small>
|
|
63
|
+
{{ success }} <span translate>of</span> {{ total }}<span ng-if="failed > 0"> - <span translate>field:</span><span class="text-error"> {{ failed }}</span></span>
|
|
64
|
+
</small>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
<br />
|
|
69
|
+
|
|
70
|
+
<div class="box-footer">
|
|
71
|
+
<div class="row">
|
|
72
|
+
<div class="col-sm-6 columns">
|
|
73
|
+
<button class="btn btn-sm btn-success" ng-click="bulk_save()"><i class="fa fa-check"></i> <span translate>Save</span></button>
|
|
74
|
+
<button class="btn btn-sm btn-danger" ng-click="bulk_cancel()"><i class="fa fa-times"></i> <span translate>Cancel</span></button>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</form>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<% end %>
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
<div ui-view>
|
|
87
|
+
<list-view buttons="buttons" tools="tools" model="'<% if model_specified? %><%= model %><% else %><%= resource %><% end %>'" objects="<%= resource.pluralize.underscore %>" title-attribute="'<%= resource_data["title-field"] || 'name' %>'" details-template="details_template" item-per-page="10" on_delete="on_delete" column_defs="columns" list-title="list_title">
|
|
88
|
+
</list-view>
|
|
89
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// <%= resource.pluralize %> Module
|
|
2
|
+
var <%= resource.pluralize %> = angular.module("<%= resource %>", ["ListView", "Filter", "Anim", "Fields",<% if have_dependency? %><% deps.each do |dependency| %> "<%= dependency.camelize %>", <% end %><% end %>]);
|
|
3
|
+
|
|
4
|
+
<%= render "js/list_view/partials/config.js" %>
|
|
5
|
+
|
|
6
|
+
<%= render "js/list_view/partials/index_controller.js" %>
|
|
7
|
+
|
|
8
|
+
<%= render "js/list_view/partials/add_controller.js" %>
|
|
9
|
+
|
|
10
|
+
<%= render "js/list_view/partials/menu.js" %>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<% unless any_tabs? %>
|
|
2
|
+
<form novalidate name="form">
|
|
3
|
+
<% fieldsets.each do |fieldset_name, fields| %>
|
|
4
|
+
|
|
5
|
+
<div class="form box box-info">
|
|
6
|
+
|
|
7
|
+
<div class="box-header">
|
|
8
|
+
<h2 class="box-title">
|
|
9
|
+
<span ng-if="!editing" translate><%= fieldset_name %></span>
|
|
10
|
+
<span ng-if="editing" translate>Edit <%= fieldset_name %></span>
|
|
11
|
+
</h2>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
<div class="box-body">
|
|
16
|
+
|
|
17
|
+
<% first = true %><% fields.each do |field_name, field_type| %>
|
|
18
|
+
<% if first %><div class="row"><% end %>
|
|
19
|
+
<div class="col-sm-4 form-group <% if not first %>pull-left col-sm-offset-2<% end %>">
|
|
20
|
+
<label><% if required_fields.include? field_name %><i class="inline fa fa-asterisk"></i> <% end %><span translate><%= attrs(field_name, 'title') || field_name.to_s.humanize.capitalize %></span> :</label><% case field_type
|
|
21
|
+
when "belongs_to", "has_many", "in" %>
|
|
22
|
+
<relation-field select2-options="select2options" <% if required_fields.include? field_name %>required="true"<% end %> title-field="'name'" model="<%= field_name %>" field-data="<%= field_name %>_data">
|
|
23
|
+
</relation-field>
|
|
24
|
+
<% when nil %>
|
|
25
|
+
<string-field model="<%= field_name %>" field-name="'<%= field_name %>'" css-class="'form-control input-lg rounded <%= field_type %>_field'" <% if required_fields.include? field_name %>required<% end %>></string-field>
|
|
26
|
+
<% else %>
|
|
27
|
+
<<%= field_type%>-field model="<%= field_name %>" field-name="'<%= field_name %>'" css-class="'form-control input-lg rounded <%= field_type %>_field'" <% if required_fields.include? field_name %>required="true"<% end %>></<%= field_type%>-field><% end %>
|
|
28
|
+
</div>
|
|
29
|
+
<% if not first %></div><% end %><% if fields.length == 1 %></div><% end %><% first = !first %><% end %>
|
|
30
|
+
</div>
|
|
31
|
+
<!-- body body -->
|
|
32
|
+
</div>
|
|
33
|
+
<!-- box -->
|
|
34
|
+
<% end %>
|
|
35
|
+
</form>
|
|
36
|
+
|
|
37
|
+
<% else %><form novalidate name="form">
|
|
38
|
+
<div class="nav-tabs-custom">
|
|
39
|
+
|
|
40
|
+
<ul class="nav nav-tabs"><% tab_count = 1 %>
|
|
41
|
+
<% tabs.each do |name, fields| %>
|
|
42
|
+
<li ng-click="activate_tab(<%= tab_count %>)" ng-class="{active: current_tab == <%= tab_count %>, tab<%= tab_count %>: current_tab == <%= tab_count %>}"><a translate><%= name %></a></li><% tab_count += 1 %><% end %>
|
|
43
|
+
</ul>
|
|
44
|
+
|
|
45
|
+
<div class="tab-content">
|
|
46
|
+
<% tab_count = 1 %><% tabs.each do |name, field_names| %>
|
|
47
|
+
|
|
48
|
+
<div ng-class="{tab-pane: true, active:current_tab == <%= tab_count %>}" ng-show="current_tab == <%= tab_count %>">
|
|
49
|
+
<h2 translate><%= name %></h2><% first = true %>
|
|
50
|
+
<% fields.each do |field_name, field_type| %><% if tab_has_field?(name, field_name) or tabs[name].include? "__all__" %>
|
|
51
|
+
|
|
52
|
+
<% if first %><div class="row"><% end %>
|
|
53
|
+
<div class="col-sm-4 columns <% if not first %>pull-left col-sm-offset-2<% end %>">
|
|
54
|
+
<div class="form-group">
|
|
55
|
+
<label class="control-label"><% if required_fields.include? field_name %><i class="inline fa fa-asterisk"></i> <% end %><span translate><%= attrs(field_name, 'title') || field_name.to_s.humanize.capitalize %></span> :</label><% case field_type
|
|
56
|
+
when "belongs_to", "has_many", "in" %>
|
|
57
|
+
<relation-field select2-options="select2options" <% if required_fields.include? field_name %>required="true"<% end %> title-field="'name'" model="<%= field_name %>" field-data="<%= field_name %>_data">
|
|
58
|
+
</relation-field>
|
|
59
|
+
<% when nil %>
|
|
60
|
+
<string-field model="<%= field_name %>" field-name="'<%= field_name %>'" css-class="'<%= field_type %>_field'" <% if required_fields.include? field_name %>required<% end %>></string-field>
|
|
61
|
+
<% else %>
|
|
62
|
+
<<%= field_type%>-field model="<%= field_name %>" field-name="'<%= field_name %>'" css-class="'<%= field_type %>_field'" <% if required_fields.include? field_name %>required="true"<% end %>></<%= field_type%>-field><% end %>
|
|
63
|
+
</div>
|
|
64
|
+
<% if not first %></div><% end %><% first = !first %><% end %><% end %>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
<% tab_count += 1 %><% end %>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</form>
|
|
72
|
+
<% end %>
|
|
73
|
+
|
|
74
|
+
<div class="row">
|
|
75
|
+
<div class="col-sm-6 columns">
|
|
76
|
+
<button class="btn btn-lg btn-success" ng-click="save(false)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save</span></button>
|
|
77
|
+
<button class="btn btn-lg btn-primary" ng-click="save(true)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save & Add Another</span></button>
|
|
78
|
+
<button class="btn btn-lg btn-danger" ng-click="cancel()"><i class="fa fa-times"></i> <span translate>Cancel</span></button>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<%= resource.pluralize %>.controller("Add<%= resource %>Controller", ["$rootScope", "Restangular", "$scope", "$state", "$stateParams", "gettext", "catch_error", function($rootScope, API, $scope, $state, $stateParams, _, catch_error){
|
|
2
|
+
|
|
3
|
+
$rootScope.section_name = _("<%= resource.underscore.pluralize.titleize %>");
|
|
4
|
+
$rootScope.section_slug = _("Add/Edit");
|
|
5
|
+
|
|
6
|
+
<% parents.each do |parent| %>
|
|
7
|
+
// ID of parent resource
|
|
8
|
+
$scope.<%= parent %>_id = $stateParams.<%= parent %>_id;
|
|
9
|
+
<% end %>
|
|
10
|
+
|
|
11
|
+
$scope.select2options = {};
|
|
12
|
+
$scope.editing = false;<% if any_tabs? %>
|
|
13
|
+
$scope.current_tab = 1;
|
|
14
|
+
$scope.activate_tab = function(tab, $event){
|
|
15
|
+
$scope.current_tab = tab;
|
|
16
|
+
};<% end %>
|
|
17
|
+
$scope.obj_id = null;
|
|
18
|
+
var is_copy = false;
|
|
19
|
+
|
|
20
|
+
<% fields.each do |name, type, to| %><% if ["belongs_to", "in", "has_many"].include? type %>
|
|
21
|
+
$scope.<%= name %>_data = {
|
|
22
|
+
type: '<%= type %>',<% if type == "in" %>
|
|
23
|
+
choices: _.sortBy([<% to.each do |choice| %>{name: "<%= choice.underscore %>", title: "<%= choice.humanize %>"},<% end %>]),
|
|
24
|
+
<% else %>
|
|
25
|
+
to: '<%= type.to %>',<% end %>
|
|
26
|
+
name: '<%= name %>'
|
|
27
|
+
};<% end %><% end %>
|
|
28
|
+
<% fields.each do |name, type, to| %><% if type == "in" %>$scope.<%= name %>_choices = _.sortBy([<% to.each do |choice| %>
|
|
29
|
+
{name: "<%= choice.underscore %>", title: "<%= choice.humanize %>"},<% end %>
|
|
30
|
+
], "title");<% end %><% end %>
|
|
31
|
+
if( $stateParams.id !== undefined ){
|
|
32
|
+
$scope.obj_id = $stateParams.id;
|
|
33
|
+
$scope.editing = true;
|
|
34
|
+
if ($scope.obj_id < 0) {
|
|
35
|
+
is_copy = true;
|
|
36
|
+
$scope.obj_id = $scope.obj_id * -1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
var obj = API.<% parents.each do |parent| %>one("<%= parent %>", $scope.<%= parent %>_id).<% end %>one("<%= resource.pluralize.underscore %>", $scope.obj_id).get()
|
|
40
|
+
.then(function(data) {
|
|
41
|
+
<% fields.each do |field_name, field_type| %>
|
|
42
|
+
$scope.<%= field_name %> = <% if not ["string", "integer", "belongs_to", "text", "has_many", "in"].include? field_type %><%= "to_#{field_type}(data.#{field_name})" %><% elsif field_type == "belongs_to" %>data.<%= field_name %>.id<% else %>data.<%= field_name %><% end %>;<% end %>
|
|
43
|
+
}, function(data){
|
|
44
|
+
catch_error(data);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
$scope.have = function(field, obj_id) {
|
|
50
|
+
var tmp = _.where($scope[field], {id: obj_id});
|
|
51
|
+
if (tmp.length > 0) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
$scope.cancel = function(){
|
|
60
|
+
$(".form input").val("");
|
|
61
|
+
$state.go("<%= resource.pluralize.underscore %>");
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
$scope.save = function(save_another){
|
|
65
|
+
$("small.error").html("");
|
|
66
|
+
$("small.error").removeClass("error");
|
|
67
|
+
|
|
68
|
+
var <%= resource.underscore %> = {<%= resource.underscore %>: {<% fields.each do |field_name, field_type| %>
|
|
69
|
+
<% if ["belongs_to"].include? field_type %><%= field_name %>_id: parseInt($scope.<%= field_name %>),<% else %><%= field_name %>: $scope.<%= field_name %>,<% end %><% end %>
|
|
70
|
+
__res__: 0
|
|
71
|
+
}};
|
|
72
|
+
if (($scope.obj_id) && (is_copy === false)) {
|
|
73
|
+
|
|
74
|
+
API.<% parents.each do |parent| %>one("<%= parent %>", $scope.<%= parent %>_id).<% end %>one("<%= resource.pluralize.underscore %>", $scope.obj_id).patch(<%= resource.underscore %>)
|
|
75
|
+
.then(function(){
|
|
76
|
+
success_message(_("<%= resource %> updated successfully."));
|
|
77
|
+
if (save_another) {
|
|
78
|
+
$(".form input").val("");
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
$state.go("<%= resource.pluralize.underscore %>");
|
|
82
|
+
}
|
|
83
|
+
}, function(data){
|
|
84
|
+
catch_error(data);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
API.<% parents.each do |parent| %>one("<%= parent %>", $scope.<%= parent %>_id).<% end %>all("<%= resource.pluralize.underscore %>").customPOST(<%= resource.underscore %>, "").then(function(){
|
|
90
|
+
success_message(_("<%= resource %> created successfully."));
|
|
91
|
+
if (save_another) {
|
|
92
|
+
$(".form input").val("");
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
$state.go("<%= resource.pluralize.underscore %>");
|
|
96
|
+
}
|
|
97
|
+
}, function(data){
|
|
98
|
+
catch_error(data);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
};
|
|
103
|
+
}]);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// <%= resource.pluralize %> configuration section ---------------------------
|
|
2
|
+
<%= resource.pluralize %>.config(["$stateProvider", function($stateProvider){
|
|
3
|
+
// Add any route you need here
|
|
4
|
+
$stateProvider.
|
|
5
|
+
state("<%= resource.pluralize.underscore %>", {
|
|
6
|
+
url: "<% parents.each do |parent| %>/<%= parent %>/:<%= parent %>_id<% end %>/<%= resource_url %>",
|
|
7
|
+
templateUrl: template_url("<%= resource_path %>/index"),
|
|
8
|
+
controller: "<%= resource %>Controller"
|
|
9
|
+
}).
|
|
10
|
+
state("<%= resource.pluralize.underscore %>.new",{
|
|
11
|
+
url: "/new",
|
|
12
|
+
templateUrl: template("<%= resource_path %>/new"),
|
|
13
|
+
controller: "Add<%= resource %>Controller"
|
|
14
|
+
}).
|
|
15
|
+
state("<%= resource.pluralize.underscore %>.edit",{
|
|
16
|
+
url: "/:id/edit",
|
|
17
|
+
templateUrl: template("<%= resource_path %>/new"),
|
|
18
|
+
controller: "Add<%= resource %>Controller"
|
|
19
|
+
});
|
|
20
|
+
}]);
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// <%= resource %> index controller -------------------------------------------------------
|
|
2
|
+
// This controller is responsible for list page (index)
|
|
3
|
+
<%= resource.pluralize %>.controller("<%= resource %>Controller", ["$rootScope", "$scope", "gettext", "Restangular", "catch_error", "$state", "$stateParams", function($rootScope, $scope, _, API, catch_error, $state, $stateParams){
|
|
4
|
+
|
|
5
|
+
$rootScope.section_name = _("<%= resource.underscore.pluralize.titleize %>");
|
|
6
|
+
$rootScope.section_slug = _("List");
|
|
7
|
+
|
|
8
|
+
<% parents.each do |parent| %>
|
|
9
|
+
// ID of parent resource
|
|
10
|
+
$scope.<%= parent %>_id = $stateParams.<%= parent %>_id;
|
|
11
|
+
<% end %>
|
|
12
|
+
|
|
13
|
+
$scope.list_title = '<%= resource %>';
|
|
14
|
+
|
|
15
|
+
$scope.tools = [
|
|
16
|
+
{
|
|
17
|
+
url: function(object) {
|
|
18
|
+
return "#" + <% parents.each do |p| %>"/<%= p %>/" + $scope.<%= p %>_id + <% end %>"/<%= resource_url %>/" + object.id + "/edit";
|
|
19
|
+
},
|
|
20
|
+
icon: 'fa fa-edit'
|
|
21
|
+
}
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
<% unless no_filter? %>$scope.filter_config = {
|
|
25
|
+
list: <% if parent? %>API.<% parents.each do |parent| %>one("<%= parent %>", $scope.<%= parent %>_id)<% end %>.all("<%= resource.pluralize.underscore %>")<% else %>API.all("<%= resource.pluralize.underscore %>")<% end %>
|
|
26
|
+
};
|
|
27
|
+
$scope.<%= resource.pluralize.underscore %> = [];<% end %>
|
|
28
|
+
<% unless no_bulk? %>// Cache object for each field name possible values
|
|
29
|
+
$scope.cache = {};
|
|
30
|
+
|
|
31
|
+
// Change event handler for field_name combobox in bulk edit
|
|
32
|
+
$scope.field_name_change = function(x){
|
|
33
|
+
var current_value = $("#field_name").val();
|
|
34
|
+
$scope.current_field= _.find($scope.fields, function(x){
|
|
35
|
+
return x.name == current_value;
|
|
36
|
+
});
|
|
37
|
+
if( "to" in $scope.current_field ){
|
|
38
|
+
if (! ($scope.current_field.name in $scope.cache)) {
|
|
39
|
+
$scope.current_field.to().then(function(x){
|
|
40
|
+
$scope.cache[$scope.current_field.name] = x;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
$scope.columns = [<% grid_fields.each do |name, type| %>
|
|
47
|
+
{field:'<%= name %>', displayName: _('<%= name.capitalize.humanize %>')},
|
|
48
|
+
<% end %>];
|
|
49
|
+
$scope.fields = [<% bulk_edit_fields.each do |name| %>
|
|
50
|
+
{
|
|
51
|
+
name: "<%= name %><% if ["belongs_to", "has_many"].include? fields_hash[name] %>_id<% end %>",
|
|
52
|
+
title: _("<%= name.capitalize.humanize %>"),
|
|
53
|
+
type: "<%= fields_hash[name] %>"<% if ["belongs_to", "has_many"].include? fields_hash[name] %>,
|
|
54
|
+
to: API.all("<%= fields_hash[name].to %>").getList<% end %>
|
|
55
|
+
},<% end %>
|
|
56
|
+
];<% end %>
|
|
57
|
+
|
|
58
|
+
// details_template is the address of template which should load for
|
|
59
|
+
// each item details section
|
|
60
|
+
$scope.details_template = template("<%= resource_path %>/details");
|
|
61
|
+
|
|
62
|
+
// Buttons for top of the list-view
|
|
63
|
+
$scope.buttons = [
|
|
64
|
+
{
|
|
65
|
+
title: _("New"),
|
|
66
|
+
icon: "fa fa-plus",
|
|
67
|
+
classes: "btn btn-success",
|
|
68
|
+
permission: {
|
|
69
|
+
name: "create",
|
|
70
|
+
model: "<% if model_specified? %><%= model %><% else %><%= resource.classify %><% end %>"
|
|
71
|
+
},
|
|
72
|
+
route: "#<% parents.each do |p| %>/<%= p %>/" + $scope.<%= p %>_id + "<% end %>/<%= resource_url %>/new"
|
|
73
|
+
|
|
74
|
+
},<% unless no_bulk? %>
|
|
75
|
+
{
|
|
76
|
+
title: _("Bulk Edit"),
|
|
77
|
+
icon: "fa fa-edit",
|
|
78
|
+
classes: "btn btn-warning",
|
|
79
|
+
permission: {
|
|
80
|
+
name: "update",
|
|
81
|
+
model: "<% if model_specified? %><%= model %><% else %><%= resource.classify %><% end %>"
|
|
82
|
+
},
|
|
83
|
+
action: function(){
|
|
84
|
+
$scope.$apply("bulk_edit = ! bulk_edit");
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
},<% end %>
|
|
88
|
+
{
|
|
89
|
+
title: _("Duplicate"),
|
|
90
|
+
icon: "fa fa-files-o",
|
|
91
|
+
classes: "btn btn-danger",
|
|
92
|
+
permission: {
|
|
93
|
+
name: "create",
|
|
94
|
+
model: "<% if model_specified? %><%= model %><% else %><%= resource.classify %><% end %>"
|
|
95
|
+
},
|
|
96
|
+
action: function(){
|
|
97
|
+
var selected = _.find($scope.<%= resource.pluralize.underscore %>, function(x){
|
|
98
|
+
return x.is_selected === true;
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
if (selected === undefined ) {
|
|
102
|
+
error_message(_("You should only select one item to copy."));
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
$state.go("<%= resource.pluralize.underscore %>.edit", {id: "-" + selected.id});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
];<% unless no_bulk? %>
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
* On bulk save event
|
|
114
|
+
*/
|
|
115
|
+
$scope.bulk_save = function(){
|
|
116
|
+
|
|
117
|
+
$scope.view_progressbar = true;
|
|
118
|
+
var value = $("#field_value").val();
|
|
119
|
+
var field = $scope.current_field.name;
|
|
120
|
+
var type = $scope.current_field.type;
|
|
121
|
+
var field_name = $scope.current_field.title;
|
|
122
|
+
if ((type == "has_many") || (type == "belongs_to")) {
|
|
123
|
+
value = parseInt(value, 10);
|
|
124
|
+
}
|
|
125
|
+
var requests_count = 0;
|
|
126
|
+
|
|
127
|
+
$scope.rfiller = 0;
|
|
128
|
+
$scope.sfiller = 0;
|
|
129
|
+
$scope.success = 0;
|
|
130
|
+
$scope.failed = 0;
|
|
131
|
+
$scope.total = _.where($scope.<%= resource.pluralize.underscore %>, function(x){return x.is_selected === true;}).length;
|
|
132
|
+
|
|
133
|
+
_.each($scope.<%= resource.pluralize.underscore %>, function(x){
|
|
134
|
+
if( x.is_selected === true ){
|
|
135
|
+
x[field] = value;
|
|
136
|
+
requests_count++;
|
|
137
|
+
|
|
138
|
+
var rwidth = (requests_count * 100) / $scope.total;
|
|
139
|
+
if (requests_count == $scope.total) { rwidth = 100; }
|
|
140
|
+
$scope.rfiller = rwidth + "%";
|
|
141
|
+
|
|
142
|
+
API.one("<%= resource.pluralize.underscore %>", x.id).patch(x).then(function(data){
|
|
143
|
+
$scope.success++;
|
|
144
|
+
var swidth = parseInt(($scope.success * 100) / $scope.total);
|
|
145
|
+
if ($scope.sucess == $scope.total) { swidth = 100; }
|
|
146
|
+
$scope.sfiller = swidth + "%";
|
|
147
|
+
x[field_name.toLowerCase()] = data[field_name.toLowerCase()];
|
|
148
|
+
}, function(data){
|
|
149
|
+
$scope.failed++;
|
|
150
|
+
catch_error(data);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/*
|
|
159
|
+
* On bulk cancel event
|
|
160
|
+
*/
|
|
161
|
+
$scope.bulk_cancel = function(){
|
|
162
|
+
$("#field_name").val(0);
|
|
163
|
+
document.getElementById("bulk_form").reset();
|
|
164
|
+
$scope.view_progressbar = false;
|
|
165
|
+
$scope.bulk_edit = false;
|
|
166
|
+
};
|
|
167
|
+
<% end %>
|
|
168
|
+
/*
|
|
169
|
+
* On delete event handler - `items` is an array of objects to delete
|
|
170
|
+
*/
|
|
171
|
+
$scope.on_delete = function(items){
|
|
172
|
+
|
|
173
|
+
var query = [];
|
|
174
|
+
items.forEach(function(item){
|
|
175
|
+
query.push(item.id);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
API.<% parents.each do |p| %>all("<%=p %>").<% end %>all("<%= resource.pluralize.underscore %>").customDELETE(query.join(","))
|
|
179
|
+
.then(function(data) {
|
|
180
|
+
|
|
181
|
+
$scope.<%= resource.pluralize.underscore %> = _.filter($scope.<%= resource.pluralize.underscore %>, function(x){
|
|
182
|
+
return !(query.indexOf(x.id) != -1);
|
|
183
|
+
});
|
|
184
|
+
success_message(data.msg);
|
|
185
|
+
}, function(data){
|
|
186
|
+
catch_error(data);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
};
|
|
190
|
+
<% unless no_filter? %>/*<% end %>
|
|
191
|
+
<% if parent? %>API.<% parents.each do |parent| %>one("<%= parent %>", $scope.<%= parent %>_id)<% end %>.all("<%= resource.pluralize.underscore %>").getList()<% else %>
|
|
192
|
+
API.all("<%= resource.pluralize.underscore %>").getList()<% end %>
|
|
193
|
+
.then(function(data){
|
|
194
|
+
$scope.<%= resource.pluralize.underscore %> = data;
|
|
195
|
+
}, function(data){
|
|
196
|
+
catch_error(data);
|
|
197
|
+
});
|
|
198
|
+
<% unless no_filter? %>*/<% end %>
|
|
199
|
+
}]);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<% if has_menu? %>
|
|
2
|
+
<%= resource.pluralize %>.controller("<%= resource %>MenuController", ["gettext", function(gettext){
|
|
3
|
+
this.menu_items = [<% resource_data["menu"].each do |menu| %>
|
|
4
|
+
{title: gettext("<%= menu["title"] %>"), url: "<%= menu["url"] %>"<% if menu.include? "model" %>, permission: {action: "<%= menu["perm_action"] || 'read' %>", model: "<%= menu["model"] %>"}<% end %>},<% end %>
|
|
5
|
+
];
|
|
6
|
+
}]);<% end %>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
+
* listed below.
|
|
4
|
+
*
|
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
|
7
|
+
*
|
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
|
10
|
+
*
|
|
11
|
+
*= require_directory .
|
|
12
|
+
*= require_self
|
|
13
|
+
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//= require dashstrap/ltr/application
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//= require dashstrap/rtl/application
|