dashboard-rails 1.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3a86427f3df1221fe3e57a76b2018089abc3264a47ab1f8ca71619cf547ae7cd
4
+ data.tar.gz: 56714713af95f13099f3721281b037a59c42a4e68dd2b55ae3c28adbc04a80d8
5
+ SHA512:
6
+ metadata.gz: 5c5c522b76dfa3d830dec7da01b35a7f67cd3331596fe34460a59c5f981fba735a5f077a9bf345cfef977f0058791ef21a2a8ac85b50f6edb5653060709797f2
7
+ data.tar.gz: 3129075c90183adc2ed987134bd164d87c2fb049878bfea9b7b9eef79d5074b32cd98a4cf76fd161e86e01a54bd1185e89016c47791cf273135df19b8cc6d613
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Daniel de Carvalho Passarini
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,198 @@
1
+ # Dashboard Rails
2
+
3
+ This Gem was designed to help create a dashboard page where the user can configure the diplayed widgets.
4
+
5
+ The user selects the widgets that he would like to display and save this information to the database so next time he
6
+ loads the application the desired widgets will be displayed.
7
+
8
+ For the moment we require a model *User* and the method *current_user*
9
+
10
+ ## TODO
11
+
12
+ - Configure page layout (number and size of columns)
13
+ - Define widgets position in the page using drag & drop
14
+ - Define the auto refrsesh interval (today fixed in 60 seconds)
15
+
16
+ ### Installation
17
+
18
+ Add the gem to the Gemfile
19
+
20
+ ```ruby
21
+ gem 'dashboard-rails'
22
+ ```
23
+ run bundle install
24
+
25
+ ```sh
26
+ $ bundle install
27
+ ```
28
+
29
+ Generate some required files using the provided install generator
30
+ ```sh
31
+ $ rails g dashboard-rails:install
32
+ ```
33
+
34
+ A migration will be created the table to keep the dashboard settings per user
35
+
36
+ ```sh
37
+ $ rake db:migrate
38
+ ```
39
+
40
+ Add the provide css to **application.css**
41
+ ```js
42
+ *= require dashboard-rails
43
+ ```
44
+
45
+ Add the provide js to **application.js**
46
+ ```js
47
+ //= require dashboard-rails
48
+ ```
49
+
50
+ ### Dashboard Page
51
+
52
+ Create you dashboard page, just add the following helper to your page
53
+
54
+ ```html
55
+ <%= dashboard_view %>
56
+ ```
57
+
58
+ Or, you can generate the dashboard viwes in your project to customize it
59
+
60
+ ```sh
61
+ rails g dashboard-rails:view
62
+ ```
63
+
64
+ ### the Dashboard Configuration Page
65
+
66
+ Create you confi dashboard page, just add the following helper to your page
67
+
68
+ ```html
69
+ <%= config_dashboard_view %>
70
+ ```
71
+
72
+
73
+ <%= config_dashboard_path %>
74
+
75
+
76
+ Or, you can generate the dashboard viwes in your project to customize it
77
+
78
+ ```sh
79
+ rails g dashboard-rails:view
80
+ ```
81
+
82
+
83
+ ### Widget Generators
84
+
85
+ To create the widget skeleton use:
86
+ ```sh
87
+ rails generate dashboard-rails:widget #{widget_name}
88
+ ```
89
+
90
+
91
+ All widgets are create under the `app/widgets` folder
92
+
93
+
94
+ ## How to create a Widget
95
+
96
+ For example:
97
+
98
+ ```ruby
99
+ class ExemploWidget < ApplicationWidget
100
+
101
+ name! 'Widget Exemplo'
102
+ description! 'Esse Widget é apenas um exemplo'
103
+
104
+ description! :executar, 'Essa ação é um outro exemplo'
105
+ def executar
106
+ @ano = params[:ano] || Date.today.year
107
+ end
108
+
109
+ end
110
+ ```
111
+
112
+ **Cada ação será uma visão diferente do widget. Exemplo: Calendário Mensal, Calendário Semanal, você terá o widget Calendários e as ações mensal e semanal.**
113
+
114
+ Parametros utilizados como documentação para exibir na lista de configuração de Widgets x Usuários.
115
+
116
+ - **name!** identifica o nome (título) do Widget.
117
+ - **description!** é a descrição (função) do Widget.
118
+ - **description! :acao** é a descrição (função) da ação daquele Widget.
119
+
120
+ O conteúdo visual do Widget (VIEW) seguirá o padrão do rails estando na pasta `app/views/widgets/nome_do_widget/nome_da_acao.html.erb`:
121
+
122
+ *app/widgets/exemplo/executar.html.erb*
123
+ ```html
124
+ <div>
125
+ Meu widget de exemplo retornou o ano: <%= @ano %>
126
+ <%= link_to 'Próximo Ano e recarregar Widget', widget_path(ano: (@ano +1), widget_ajax: true %>
127
+ <%= link_to 'Ir para página externa normalmente', 'http://www.google.com.br/' %>
128
+ </div>
129
+ ```
130
+
131
+ Para direcionar o usuário para configurar seus widgets, faça um link para `dashboard-rails_path`
132
+ ```html
133
+ <%= link_to 'Gerenciar Widgets', dashboard-rails_path %>
134
+
135
+ <%= link_to 'Gerenciar Widgets', dashboard_settings_path %>
136
+
137
+
138
+ ```
139
+
140
+ ### Helpers
141
+
142
+ Para verificar a permissão de acesso ao Widget pelo usuário atual (current_user), utilize o helper `user_can_widget?(nome_widget, ação)`:
143
+ ```html
144
+ <% if show_widget?(:calendarios, :mensal) %>
145
+
146
+ <% end %>
147
+ ```
148
+
149
+ Para adicionar um widget use o helper `add_widget(nome_widget, ação)`:
150
+ ```html
151
+ <%= add_widget(:calendarios, :mensal) %>
152
+ ```
153
+
154
+ Para referenciar um path do widget de forma automática utilize `widget_path`. Esse helper espera que haja definido em params *widget_name* e *widget_name* :
155
+ ```html
156
+ <!-- ESPERA QUE EXISTA params[:widget_name] e params[:widget_action] definidos -->
157
+ <%= widget_path(novo_atributo: 'novo valor') %>
158
+ ```
159
+
160
+ Para criar um link que faça uma chamada ajax e retorne o resultado HTML no próprio widget (como mudar de página por exemplo):
161
+ ```html
162
+ <%= link_to 'Link Remoto', widget_path({ano: @ano}), widget_ajax: true %>
163
+ ```
164
+
165
+ Formulário para reescrever o plugin baseado em algum parametro:
166
+ ```html
167
+ <%= form_tag widget_path, method: :get, widget_ajax: true do %>
168
+
169
+ <% end %>
170
+ ```
171
+
172
+ ### Atualização Manual do Widget
173
+
174
+ Para atualizar um widget de forma manual você precisa recuperar o elemento do widget com a classe `widget` e chamar o método `widget_load_from_ajax`:
175
+ ```javascript
176
+ var elemento = $('.widget:first')
177
+ //Esse elemento precisa ser um elemento jQuery
178
+ widget_load_from_ajax(elemento);
179
+ ```
180
+
181
+ ### Recursos AJAX (automáticos)
182
+
183
+ Toda vez que um elemento com classe `widget-user-control` for alterado será disparado um evento AJAX que irá localizar as configuraçẽos do usuário na view de configuração e retornará um HTML com o conteúdo no elemento `.widgets_list .list`. Caso não seja informado esse item, o primeiro formulário com a classe `widget_config` será passado como elemento destino.
184
+
185
+ Todo formulário em widget que tenha a atributo `widget_ajax` terá seu evento "submit" enviado por AJAX, retornando o resultado no próprio container do widget, portanto é esperado um retorno HTML.
186
+
187
+ Todo elemento com atributo `data-url` tentará criar um contador com tempo igual ao atributo `data-tick` para atualização automática do widget.
188
+
189
+
190
+
191
+ # Developers
192
+
193
+ To publish this gem use:
194
+
195
+ ```sh
196
+ gem push dashboard-rails-0.1.0.gem
197
+
198
+ ```
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ # require 'rdoc/task'
8
+ # RDoc::Task.new(:rdoc) do |rdoc|
9
+ # rdoc.rdoc_dir = 'rdoc'
10
+ # rdoc.title = 'DashboardRails'
11
+ # rdoc.options << '--line-numbers'
12
+ # rdoc.rdoc_files.include('README.rdoc')
13
+ # rdoc.rdoc_files.include('lib/**/*.rb')
14
+ # end
15
+
16
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
17
+ load 'rails/tasks/engine.rake'
18
+
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ # require 'rake/testtask'
25
+ #
26
+ # Rake::TestTask.new(:test) do |t|
27
+ # t.libs << 'lib'
28
+ # t.libs << 'test'
29
+ # t.pattern = 'test/**/*_test.rb'
30
+ # t.verbose = false
31
+ # end
32
+ #
33
+ #
34
+ # task default: :test
@@ -0,0 +1,119 @@
1
+ function hasParams(url) {
2
+ var regex = new RegExp(/\?\w+\=/);
3
+ regex.test(url);
4
+ }
5
+
6
+ function widget_load_from_ajax($el, new_url) {
7
+ if ($el!=undefined && $el!=null && $el instanceof jQuery) {
8
+ var dest_url = (new_url != undefined ? new_url : $el.attr('data-url'));
9
+ // var query_string = window.location.search.substring(1);
10
+ // if (query_string!=undefined && query_string!=null) {
11
+ // dest_url = dest_url + (hasParams(dest_url) ? '&' : '?') + query_string;
12
+ // }
13
+ $.ajax({
14
+ url: dest_url,
15
+ method: 'get',
16
+ dataType: 'html',
17
+ beforeSend: function (jqXHR, settings) {
18
+ widget_loading($el);
19
+ },
20
+ success: function (data, textStatus, jqXHR) {
21
+ //console.log('sucesso');
22
+ $el.html(data);
23
+ if (new_url != undefined) {
24
+ $el.attr('data-url', new_url);
25
+ }
26
+ },
27
+ error: function (jqXHR, textStatus, errorThrown) {
28
+ console.log('erro',jqXHR);
29
+ },
30
+ complete: function (jqXHR, textStatus) {
31
+ widget_loading($el, false);
32
+ }
33
+ });
34
+ } else {
35
+ alert('Erro! Objeto Widget Não encontrado!');
36
+ }
37
+ }
38
+
39
+ function widget_load_user_config(user_id, elDestBlock) {
40
+ var $elDestBlock = $('.widget_config');
41
+ var $elDestList = $elDestBlock.find('.widgets_list .list');
42
+ $.ajax({
43
+ url: '/dashboard-rails/widgets/user/'+user_id,
44
+ method: 'get',
45
+ dataType: 'html',
46
+ beforeSend: function (jqXHR, settings) {
47
+ widget_loading($elDestBlock);
48
+ },
49
+ success: function (data, textStatus, jqXHR) {
50
+ // console.log(data);
51
+ $elDestList.html(data);
52
+ },
53
+ error: function (jqXHR, textStatus, errorThrown) {
54
+ console.log('erro',jqXHR);
55
+ },
56
+ complete: function (jqXHR, textStatus) {
57
+ widget_loading($elDestBlock, false);
58
+ }
59
+ });
60
+ }
61
+
62
+ function widget_loading(element, state) {
63
+ var $el = $(element);
64
+ if (state==undefined) state=true;
65
+
66
+ if (state==true) {
67
+ $("<div class='widget_loading'><span>Carregando...</span></div>").appendTo($el);
68
+ } else {
69
+ $el.find('.widget_loading').fadeOut('fast', function(){
70
+ $(this).remove();
71
+ });
72
+ }
73
+ }
74
+
75
+ //FORMS
76
+ $(document).on('submit','form[widget_ajax]', function(ev) {
77
+ ev.preventDefault();
78
+ var widget_element = $(this).closest('.widget'),
79
+ atributos = $(this).serialize(),
80
+ form_url = $(this).attr('action');
81
+ if (atributos!=undefined && atributos!=null) {
82
+ form_url = form_url + (hasParams(form_url) ? '&' : '?') + atributos;
83
+ }
84
+ widget_load_from_ajax(widget_element, form_url);
85
+ });
86
+
87
+ //LINKS
88
+ $(document).on('click','a[widget_ajax]', function(ev) {
89
+ ev.preventDefault();
90
+ var widget_element = $(this).closest('.widget');
91
+ var new_url = $(this).attr('href');
92
+ widget_load_from_ajax(widget_element, new_url);
93
+ });
94
+
95
+ //USER CONTORL
96
+ $(document).on('change','.widget-user-control', function(ev) {
97
+ var $el = $(this);
98
+ widget_load_user_config($el.val());
99
+ });
100
+
101
+ $(document).on('ready',function(){
102
+
103
+ $('.widget[data-url]').each(function(i,el) {
104
+ var $el = $(el);
105
+ var delay_in_ms = $el.attr('data-tick') || 0;
106
+ widget_load_from_ajax($el);
107
+ if (delay_in_ms > 0) {
108
+ window.setInterval(function(){ widget_load_from_ajax($el); }, delay_in_ms);
109
+ }
110
+ });
111
+
112
+ //INIT
113
+ if ($('.widget-user-control').length > 0) {
114
+ $('.widget-user-control').trigger('change');
115
+ } else {
116
+ widget_load_user_config('');
117
+ }
118
+
119
+ });
@@ -0,0 +1,40 @@
1
+ .widget {
2
+ position: relative;
3
+ min-height: 50px;
4
+ }
5
+
6
+ .widgets_list ul {
7
+ padding-left: 0px;
8
+ }
9
+
10
+ .widgets_list ul li {
11
+ list-style: none;
12
+ }
13
+
14
+ .widget_loading {
15
+ position: absolute;
16
+ width: 100%;
17
+ height: 100%;
18
+ min-height: 50px;
19
+ top: 0;
20
+ left: 0;
21
+ background-color: #ccc;
22
+ opacity: 0.5;
23
+ border-radius: 5px;
24
+ cursor: not-allowed;
25
+ }
26
+
27
+ .widget_loading span {
28
+ background-color: #FFF;
29
+ font-size: 18px;
30
+ color: #000;
31
+ padding: 5px;
32
+ font-weight: bold;
33
+ margin: 0;
34
+ border-radius: 5px;
35
+ position: absolute;
36
+ top: 50%;
37
+ left: 50%;
38
+ margin-right: -50%;
39
+ transform: translate(-50%, -50%);
40
+ }
@@ -0,0 +1,56 @@
1
+ class ApplicationWidget < ::ApplicationController
2
+ include SingletonHelper
3
+
4
+ attr_singleton :refresh_interval, 0
5
+
6
+ def initialize(request)
7
+ self.request = request
8
+ end
9
+
10
+ def render_template(view_file=nil, *args)
11
+ args << {template: view_file}
12
+ render_to_string *args
13
+ end
14
+
15
+ def view(view_file=nil, klass=nil)
16
+ class_caller = klass || (caller[0].match(/(\b\w+)\.rb/)[1] rescue '')
17
+ action_caller = view_file || (caller[0].match(/`(.*)'/)[1] rescue '')
18
+ view_file = "widgets/#{class_caller.to_s.sub('_widget','')}/#{action_caller}" unless lookup_context.find_all(view_file).any?
19
+ instance_variable_set(:@view_file, view_file)
20
+ end
21
+
22
+ def self.name?
23
+ instance_variable_defined?(:@widget_name) ? instance_variable_get(:@widget_name) : ''
24
+ end
25
+
26
+ def self.name!(value)
27
+ # define_singleton_method(:widget_name) {value}
28
+ instance_variable_set(:@widget_name, value)
29
+ end
30
+
31
+ def self.description?(attr=nil)
32
+ attr='widget' if attr.nil?
33
+ instance_variable_defined?("@description_#{attr}") ? instance_variable_get("@description_#{attr}") : ''
34
+ end
35
+
36
+ def self.description!(*args)
37
+ if args.size == 1
38
+ instance_variable_set(:@description_widget, args[0])
39
+ elsif args.size == 2
40
+ instance_variable_set("@description_#{args[0]}", args[1])
41
+ end
42
+ end
43
+
44
+ def self.widgets
45
+ # ApplicationWidget.descendants.map do |klass| #Não estava carregando no primeiro load...
46
+ Dir["#{Rails.root}/app/widgets/*.rb"].map do |file_path|
47
+ file_name = File.basename(file_path, ".rb")
48
+ klass = Object.const_get file_name.classify
49
+ actions = klass.instance_methods(false).map do |action|
50
+ {name: action, description: klass.description?(action)}
51
+ end
52
+ {code: klass.to_s.tableize.sub('_widgets',''), name: klass.name?, description: klass.description?, actions: actions}
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,5 @@
1
+ module DashboardRails
2
+ class ApplicationController < ::ApplicationController #< ActionController::Base #ENGINE
3
+
4
+ end
5
+ end
@@ -0,0 +1,46 @@
1
+ require_dependency "dashboard-rails/application_controller"
2
+
3
+ module DashboardRails
4
+ class WidgetsController < ApplicationController
5
+
6
+ def load
7
+ widget = DashboardRails::Widget.new(params[:widget_name], self.request)
8
+ content = widget.html(params[:widget_action])
9
+ rescue Exception => e
10
+ content = e.message
11
+ ensure
12
+ render html: content, layout: false
13
+ end
14
+
15
+ def user
16
+ user_id = params[:id]
17
+ @widgets_code = DashboardRails::User.where(user_id: user_id).pluck(:widget, :action).map{|r| "#{r[0]}_#{r[1]}"}
18
+ render partial: 'widgets_list'
19
+ end
20
+
21
+ def index
22
+ @user_id = params[:user_id] || current_user.id
23
+ end
24
+
25
+ def save
26
+ user_id = params[:user_id]
27
+ widgets = params[:widgets]
28
+ widget_name_user = []
29
+ action_user = []
30
+ if user_id.present? && widgets.present?
31
+ widgets.each do |widget|
32
+ widget_name, action = widget.split('|')
33
+ if widget_name && action
34
+ widget_name_user << widget_name
35
+ action_user << action
36
+ DashboardRails::User.find_or_create_by(widget: widget_name, action: action, user_id: user_id)
37
+ end
38
+ end
39
+ end
40
+ DashboardRails::User.where(user_id: user_id).where.not(widget: widget_name_user, action: action_user).destroy_all
41
+ flash[:success] = 'Alterações foram salvas com sucesso!'
42
+ redirect_to dashboard-rails_path(user_id: user_id)
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,20 @@
1
+ module DashboardRails
2
+ module ApplicationHelper
3
+
4
+ def add_widget(widget_name, widget_action)
5
+ widget = DashboardRails::Widget.new(widget_name, self.request)
6
+ content_tag(:div, '', id: "widget_#{widget_name}_#{widget_action}", class: 'widget', data: {tick: widget.param(:refresh_interval), url: dashboard-rails_load_path(widget_name: widget_name, widget_action: widget_action)})
7
+ end
8
+
9
+ def widget_path(args=nil)
10
+ my_params = {widget_name: params[:widget_name], widget_action: params[:widget_action]}
11
+ my_params.merge!(args) if args.present?
12
+ dashboard-rails_load_path(my_params)
13
+ end
14
+
15
+ def user_can_widget?(widget_name, widget_action)
16
+ DashboardRails::User.where(user_id: current_user.id, widget: widget_name, action: widget_action).count > 0
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ module DashboardRails
2
+ class User < ActiveRecord::Base
3
+
4
+ self.table_name = :dashboard_settings
5
+ belongs_to :user
6
+ validates :widget, :action, presence: true
7
+
8
+ end
9
+ end
@@ -0,0 +1,24 @@
1
+ <% ApplicationWidget.widgets.each do |widget| %>
2
+ <ul>
3
+ <li>
4
+ <b><%= widget[:name] %></b>
5
+ <br><span class="help-block"><%= widget[:description] %></span>
6
+ <ul>
7
+ <% widget[:actions].each do |action| %>
8
+ <% widget_code = "#{widget[:code]}_#{action[:name]}" %>
9
+ <li>
10
+ <div class="checkbox">
11
+ <%= label_tag widget_code do %>
12
+ <%= check_box_tag 'widgets[]', "#{widget[:code]}|#{action[:name]}", @widgets_code.include?(widget_code), {id: widget_code} %>
13
+ <b><%= action[:name].to_s.humanize %></b>
14
+ <% if action[:description].present? %>
15
+ <br><span class="help-block"><%= action[:description] %></span>
16
+ <% end %>
17
+ <% end %>
18
+ </div>
19
+ </li>
20
+ <% end %>
21
+ </ul>
22
+ </li>
23
+ </ul>
24
+ <% end %>
@@ -0,0 +1,25 @@
1
+ <div class="row">
2
+ <div class="col-md-12">
3
+ <div class="panel panel-default">
4
+ <div class="panel-heading">
5
+ <div class="panel-title">Selecione os Widgets que deseja utilizar:</div>
6
+ </div>
7
+ <div class="panel-body">
8
+ <%= form_tag(dashboard-rails_save_path, method: :put, class: 'widget_config') do %>
9
+
10
+ <div class="form-group">
11
+ <label class="control-label">Usuário:</label>
12
+ <%= select_tag :user_id, options_from_collection_for_select(User.all, :id, :email, current_user.id), include_blank: false, class: 'form-control widget-user-control' %>
13
+ </div>
14
+
15
+ <fieldset class="widgets_list">
16
+ <legend>Widgets</legend>
17
+ <div class="list"></div>
18
+ </fieldset>
19
+
20
+ <%= submit_tag "Salvar", class: 'btn btn-success' %>
21
+ <% end %>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ </div>
@@ -0,0 +1 @@
1
+ Rails.application.config.assets.precompile += %w( dashboard-rails.js dashboard-rails.css )
@@ -0,0 +1,19 @@
1
+ Rails.application.routes.draw do
2
+
3
+
4
+ namespace :dashboard-rails do
5
+
6
+ get 'widgets/load/:widget_name/:widget_action', to: 'widgets#load', as: 'load'
7
+ get 'widgets/user(/:id)', to: 'widgets#user', as: 'user'
8
+ get 'widgets', to: 'widgets#index', as: ''
9
+ put 'widgets/save', to: 'widgets#save', as: 'save'
10
+
11
+
12
+ end
13
+
14
+
15
+
16
+
17
+
18
+
19
+ end
@@ -0,0 +1,8 @@
1
+ # require 'haml'
2
+ require 'dashboard-rails/engine'
3
+ require 'dashboard-rails/singleton_helper'
4
+ require 'dashboard-rails/widget'
5
+
6
+ module DashboardRails
7
+ # Mime::Type.register "application/vnd.ms-excel", :xls
8
+ end
@@ -0,0 +1,6 @@
1
+ module DashboardRails
2
+ class Engine < ::Rails::Engine
3
+ # config.eager_load_paths << DashboardRails::Engine.root.join('app','widgets')
4
+ config.autoload_paths << DashboardRails::Engine.root.join('app','widgets')
5
+ end
6
+ end
@@ -0,0 +1,19 @@
1
+ module SingletonHelper
2
+
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def attr_singleton(attr, default=nil)
9
+ define_singleton_method attr do |value=nil|
10
+ if value.present?
11
+ instance_variable_set("@#{attr}", value)
12
+ else
13
+ instance_variable_get("@#{attr}") || default
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,3 @@
1
+ module DashboardRails
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,23 @@
1
+ module DashboardRails
2
+ class Widget
3
+
4
+ attr_accessor :widget, :klass
5
+
6
+ def initialize(widget_name, request)
7
+ @klass_name = widget_name
8
+ @klass = Object.const_get "#{@klass_name}_widget".classify
9
+ @widget = @klass.new(request)
10
+ end
11
+
12
+ def param(param)
13
+ @klass.send(param)
14
+ end
15
+
16
+ def html(action)
17
+ content = @widget.send(action)
18
+ view_file = (@widget.instance_variables.include?(:@view_file) ? @widget.instance_variable_get(:@view_file) : @widget.view(action, @klass_name))
19
+ @widget.render_template(view_file) # rescue content
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ require 'rails/generators/base'
2
+ require 'rails/generators/migration'
3
+
4
+ module DashboardRails
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("../../templates", __FILE__)
7
+ include Rails::Generators::Migration
8
+
9
+ class_option :orm
10
+ desc 'Instalando Taxweb Widgets'
11
+
12
+ desc 'Criando Migrations'
13
+ def self.next_migration_number(path)
14
+ unless @prev_migration_nr
15
+ @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
16
+ else
17
+ @prev_migration_nr += 1
18
+ end
19
+ @prev_migration_nr.to_s
20
+ end
21
+
22
+ def create_migration_file
23
+ migration_template 'create_dashboard-rails_users.rb', 'db/migrate/create_dashboard-rails_users.rb'
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ require 'rails/generators/base'
2
+
3
+ module DashboardRails
4
+ class ViewGenerator < Rails::Generators::Base
5
+ source_root File.expand_path("../../../../app/views/dashboard-rails", __FILE__)
6
+
7
+ def copy_views
8
+ directory 'widgets', 'app/views/dashboard-rails/widgets'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ require 'rails/generators/base'
2
+
3
+ module DashboardRails
4
+ class WidgetGenerator < Rails::Generators::NamedBase
5
+ source_root File.expand_path("../../templates", __FILE__)
6
+
7
+ def generate_widget
8
+ @widget_name = file_name.classify
9
+ view_dir = "app/views/widgets/#{widget_name_file}"
10
+
11
+ template "generic_widget.erb", File.join('app/widgets', "#{widget_name_file}_widget.rb")
12
+
13
+ if self.behavior == :revoke && Dir.exists?(view_dir)
14
+ require 'fileutils'
15
+ FileUtils.rm_rf(view_dir)
16
+ elsif self.behavior == :invoke
17
+ copy_file "generic_widget.html.erb", File.join(view_dir, 'exemplo.html.erb')
18
+ end
19
+ end
20
+
21
+ def widget_name_file
22
+ file_name.underscore
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ class CreateDashboardSettings < ActiveRecord::Migration
2
+
3
+ def up
4
+ unless table_exists?(:dashboard_settings)
5
+ create_table :dashboard_settings do |t|
6
+ t.references :user, index: true, foreign_key: false
7
+ t.string :widget
8
+ t.string :action
9
+ t.index [:widget, :action]
10
+ end
11
+ end
12
+ end
13
+
14
+ def down
15
+ drop_table :dashboard_settings if table_exists? :dashboard_settings
16
+ end
17
+
18
+ end
@@ -0,0 +1,12 @@
1
+ class <%= @widget_name %>Widget < ApplicationWidget
2
+
3
+ name! "<%= @widget_name %>"
4
+ description! "O Widget <%= @widget_name %> tem como função..."
5
+ #refresh_interval 60000 #60 segundos para refresh automático
6
+
7
+ description! :exemplo, 'Essa ação é um exemplo'
8
+ def exemplo
9
+ @data = Date.today
10
+ end
11
+
12
+ end
@@ -0,0 +1,2 @@
1
+ <h1>Exemplo de Widget<h1>
2
+ Hoje é <%= data %>
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dashboard-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - TaxWeb
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5'
33
+ description: Gerenciamento de Widgets para Dashboard
34
+ email:
35
+ - produto@taxweb.com.br
36
+ executables: []
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - MIT-LICENSE
41
+ - README.md
42
+ - Rakefile
43
+ - app/assets/javascripts/dashboard-rails.js
44
+ - app/assets/stylesheets/dashboard-rails.css
45
+ - app/controllers/application_widget.rb
46
+ - app/controllers/dashboard-rails/application_controller.rb
47
+ - app/controllers/dashboard-rails/widgets_controller.rb
48
+ - app/helpers/dashboard-rails/application_helper.rb
49
+ - app/models/dashboard-rails/user.rb
50
+ - app/views/dashboard-rails/widgets/_widgets_list.html.erb
51
+ - app/views/dashboard-rails/widgets/index.html.erb
52
+ - config/initializers/assets.rb
53
+ - config/routes.rb
54
+ - lib/dashboard-rails.rb
55
+ - lib/dashboard-rails/engine.rb
56
+ - lib/dashboard-rails/singleton_helper.rb
57
+ - lib/dashboard-rails/version.rb
58
+ - lib/dashboard-rails/widget.rb
59
+ - lib/generators/dashboard-rails/install_generator.rb
60
+ - lib/generators/dashboard-rails/view_generator.rb
61
+ - lib/generators/dashboard-rails/widget_generator.rb
62
+ - lib/generators/templates/create_taxweb_widgets_users.rb
63
+ - lib/generators/templates/generic_widget.erb
64
+ - lib/generators/templates/generic_widget.html.erb
65
+ homepage: http://www.taxweb.com.br
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.7.8
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Gerenciamento de Widgets para Dashboard
89
+ test_files: []