sinatra-hexacta 0.9.12 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc4e539f65371ebb4d52b73e185f6d41bf0576d568ca371150b6bbe9e4d0c49c
4
- data.tar.gz: 841dc6b738b38f5afcdbf7b73dc23c9d57a7d7111d890c6f7457ee7fb8cfb82b
3
+ metadata.gz: df6a0ef3c8ba7cdd6d652d08a0c930519dca2aec379bd3275d24fb99f839129e
4
+ data.tar.gz: c47bab0989ad1a159a308cdc3c229c121293e6d483b14dce97efe0ced18474aa
5
5
  SHA512:
6
- metadata.gz: 2240105d063c417614628c4ae4da5e9e4271d4d9e290d1aafba2421c9c7fff265bc5b519f99ff6281fb193755f166ae85ee657c23167ddf68f856c0ac83fe5cc
7
- data.tar.gz: 643d0ac518473058ba06466037125019ff852fe03cfaf71b0b9cd1700c224fee5e80b77cc9df42a564c6d5d4102c87d33456e64a91881d947b3c6b3a5c21fa9e
6
+ metadata.gz: fafe733141d4516b0f0b360097ad195b638fced57dce48fd5fefe1fd0b968ef54afeae4720744827e60ae3742d8ed1870063eb30e9c71c9ee4072ffd9f246353
7
+ data.tar.gz: d19d3fb7fdc997ad5a4fddefcb1680e4b07e9bc7270b1373617b6688a8ca45ebffd68e706f78bd96ba2acaeff1def4e3488466da11bd53c55dd4b8d0ca3458a1
@@ -5,16 +5,16 @@ class Antiquity
5
5
  @periods = periods.sort { |a,b| a.start_date <=> b.start_date }
6
6
  end
7
7
 
8
- def days
9
- @periods.inject(0) { |total, period| total + period.days }
8
+ def days(upto_date=Date.today)
9
+ @periods.inject(0) { |total, period| total + period.days(upto_date) }
10
10
  end
11
11
 
12
- def months
13
- @periods.inject(0) { |total, period| total + period.months }
12
+ def months(upto_date=Date.today)
13
+ @periods.inject(0) { |total, period| total + period.months(upto_date) }
14
14
  end
15
15
 
16
- def years
17
- months.divmod(12).first
16
+ def years(upto_date=Date.today)
17
+ months(upto_date).divmod(12).first
18
18
  end
19
19
 
20
20
  def to_s(upto_date=Date.today)
@@ -22,11 +22,13 @@ class Antiquity
22
22
  result = ""
23
23
  return result if @periods.empty?
24
24
  if date >= @periods.first.start_date
25
- result += years > 1 ? "#{years} años" : "#{years} año" unless years == 0
26
- result += ", " if years >= 1 && !(months.modulo(12).eql?(0))
27
- result += months.modulo(12) > 1 ? "#{months.modulo(12)} meses" : "#{months.modulo(12)} mes" unless months.modulo(12) == 0
28
- result += "#{(date - @periods.last.start_date).to_i} dias" if months.modulo(12) == 0 && years == 0 && date > @periods.last.start_date
29
- result += "Hoy!" if months.modulo(12) == 0 && date == @periods.last.start_date
25
+ years_upto_date = years(date)
26
+ months_upto_date = months(date)
27
+ result += years_upto_date > 1 ? "#{years_upto_date} años" : "#{years_upto_date} año" unless years_upto_date == 0
28
+ result += ", " if years_upto_date >= 1 && !(months_upto_date.modulo(12).eql?(0))
29
+ result += months_upto_date.modulo(12) > 1 ? "#{months_upto_date.modulo(12)} meses" : "#{months_upto_date.modulo(12)} mes" unless months_upto_date.modulo(12) == 0
30
+ result += "#{(date - @periods.last.start_date).to_i} dias" if months_upto_date.modulo(12) == 0 && years_upto_date == 0 && date > @periods.last.start_date
31
+ result += "Hoy!" if months_upto_date.modulo(12) == 0 && date == @periods.last.start_date
30
32
  end
31
33
  result += "En unos días..." if date < @periods.first.start_date
32
34
  result
@@ -3,6 +3,7 @@
3
3
  class AsyncProcess
4
4
  include SuckerPunch::Job
5
5
  attr_reader :handler
6
+ attr_reader :user_id
6
7
  end
7
8
 
8
9
  class ExampleProcess < AsyncProcess
@@ -25,10 +26,10 @@ end
25
26
 
26
27
  class ProcessHandler
27
28
 
28
- attr_reader :log, :error, :interrupted, :name, :id, :performed, :total, :clazz
29
+ attr_reader :log, :error, :interrupted, :name, :id, :performed, :total, :clazz, :user_id
29
30
  attr_accessor :total
30
31
 
31
- def initialize(id, name, clazz)
32
+ def initialize(id, name, clazz, user_id)
32
33
  @id = id
33
34
  @total = 0
34
35
  @performed = 0
@@ -37,6 +38,7 @@ class ProcessHandler
37
38
  @interrupted = false
38
39
  @name = name
39
40
  @clazz = clazz
41
+ @user_id = user_id
40
42
  end
41
43
 
42
44
  def progress
@@ -74,21 +76,22 @@ class ProcessManager
74
76
  @handlers = []
75
77
  end
76
78
 
77
- def find(clazz)
78
- @handlers.find { |handler| handler.clazz == clazz }
79
+ def find(clazz,user_id)
80
+ @handlers.find { |handler| handler.clazz == clazz && handler.user_id == user_id }
79
81
  end
80
82
 
81
83
  def run(*args)
82
- clean(args.first.to_s)
83
- if !running?(args.first.to_s)
84
- handler = ProcessHandler.new(rand(1..100000000), args.first.name, args.first.to_s)
84
+ user_id = args[1][:user_id]
85
+ clean(args.first.to_s,user_id)
86
+ if !running?(args.first.to_s,user_id)
87
+ handler = ProcessHandler.new(rand(1..100000000), args.first.name, args.first.to_s, user_id)
85
88
  clazz = args.first
86
89
  args[0] = handler
87
90
  clazz.perform_async(*args)
88
91
  @handlers << handler
89
92
  handler
90
93
  else
91
- find(args.first.to_s)
94
+ find(args.first.to_s,user_id)
92
95
  end
93
96
  end
94
97
 
@@ -96,15 +99,15 @@ class ProcessManager
96
99
  @handlers -= [handler]
97
100
  end
98
101
 
99
- def clean(clazz)
100
- @handlers.select { |handler| handler.clazz == clazz }.each do |handler|
102
+ def clean(clazz,user_id)
103
+ @handlers.select { |handler| handler.clazz == clazz && handler.user_id == user_id }.each do |handler|
101
104
  handler.interrupt
102
105
  self.finish(handler)
103
106
  end
104
107
  end
105
108
 
106
- def running?(clazz)
107
- !@handlers.select { |handler| handler.clazz == clazz }.empty?
109
+ def running?(clazz,user_id)
110
+ !@handlers.select { |handler| handler.clazz == clazz && handler.user_id == user_id }.empty?
108
111
  end
109
112
 
110
113
  end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+ module Sinatra
3
+ module ConstantHandler
4
+ extend Hexacta
5
+
6
+ def enable_constants
7
+ p "Enabling constants..."
8
+
9
+ before '/constant*' do
10
+ error(403) if authenticated(User).permissions.empty? && authenticated(User).recruiter.nil?
11
+ end
12
+
13
+ get '/constants' do
14
+ params[:format] = 'group' if params[:format].nil?
15
+ query = Constant.where(:kind => Constant.descendants.collect { |constant_class| constant_class.to_s })
16
+ slim :"#{Hexacta::GEM_FILE_DIR}/constants/#{params[:format]}", locals: { :constants => query.order(:kind,:value).all, :total => query.count, :filters => params, :query => query }
17
+ end
18
+
19
+ post '/constant' do
20
+ attributes = params.select { |attribute| Constant.columns.include?(attribute.to_sym) }
21
+ if params[:values].nil?
22
+ constant = Constant.create(attributes)
23
+ else
24
+ for value in params[:values].split(',')
25
+ attributes[:value] = value
26
+ constant = Constant.find_or_create(attributes)
27
+ end
28
+ end
29
+ redirect back
30
+ end
31
+
32
+ post '/constants/:id' do |id|
33
+ constant = Constant.find(:id => id.to_i)
34
+ constant.update_fields(params, Constant.columns, :missing=>:skip)
35
+ constant.save #This is import to force before save
36
+ redirect back
37
+ end
38
+
39
+ delete '/constants/:id' do |id|
40
+ constant = Constant.find(:id => id.to_i)
41
+ constant.destroy.to_hash.to_json
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+
48
+ register ConstantHandler
49
+ end
@@ -4,3 +4,4 @@ require_relative 'notifications'
4
4
  require_relative 'params'
5
5
  require_relative 'reports'
6
6
  require_relative 'processes'
7
+ require_relative 'constants'
@@ -7,17 +7,19 @@ module Sinatra
7
7
  p "Enabling processes..."
8
8
 
9
9
  get '/processes' do
10
- return "" if ProcessManager.instance.find(params[:class]).nil?
10
+ return "" if ProcessManager.instance.find(params[:class],authenticated(User).id).nil?
11
11
  content_type :json
12
- return { 'name' => ProcessManager.instance.find(params[:class]).name, 'progress' => ProcessManager.instance.find(params[:class]).progress }.to_json
12
+ process = ProcessManager.instance.find(params[:class],authenticated(User).id)
13
+ return { 'name' => process.name, 'progress' => process.progress }.to_json
13
14
  end
14
15
 
15
16
  post '/processes/:clazz' do |clazz|
16
- ProcessManager.instance.clean(clazz)
17
+ ProcessManager.instance.clean(clazz,authenticated(User).id)
17
18
  200
18
19
  end
19
20
 
20
21
  post '/process' do
22
+ params[:user_id] = authenticated(User).id
21
23
  klass = Object.const_get("#{params[:class]}")
22
24
  a_handler = ProcessManager.instance.run(klass,params)
23
25
  a_handler.to_json
@@ -1,56 +1,59 @@
1
- .ct-chart.bar-chart id="#{id}"
1
+ -if labels.empty? || series.empty?
2
+ == empty_alert({ :title => "Sin datos suficientes", :message => "No hay suficientes datos para mostrar esta información."})
3
+ -else
4
+ .ct-chart.bar-chart id="#{id}"
2
5
 
3
- .table-responsive.chart-table
4
- table.table.table-striped
5
- tbody
6
- tr
7
- -for label in labels
8
- th #{label}
9
- -for serie in series
6
+ .table-responsive.chart-table
7
+ table.table.table-striped
8
+ tbody
10
9
  tr
11
- -for element in serie
12
- td #{element}
10
+ -for label in labels
11
+ th #{label}
12
+ -for serie in series
13
+ tr
14
+ -for element in serie
15
+ td #{element}
13
16
 
14
17
 
15
- javascript:
16
- var labels = #{{labels}};
17
- var series = #{{series}};
18
+ javascript:
19
+ var labels = #{{labels}};
20
+ var series = #{{series}};
18
21
 
19
- var options = {
20
- seriesBarDistance: 30,
21
- fullWidth: true,
22
- chartPadding: {
23
- right: 40
24
- },
25
- height: '300px',
26
- showLabel: true,
27
- plugins: [
28
- Chartist.plugins.legend({
29
- legendNames: #{{names}},
30
- })
31
- ]
32
- };
22
+ var options = {
23
+ seriesBarDistance: 30,
24
+ fullWidth: true,
25
+ chartPadding: {
26
+ right: 40
27
+ },
28
+ height: '300px',
29
+ showLabel: true,
30
+ plugins: [
31
+ Chartist.plugins.legend({
32
+ legendNames: #{{names}},
33
+ })
34
+ ]
35
+ };
33
36
 
34
- var responsiveOptions = [
35
- ['screen and (max-width: 640px)', {
36
- seriesBarDistance: 5,
37
- axisX: {
38
- labelInterpolationFnc: function (value) {
39
- return value[0];
37
+ var responsiveOptions = [
38
+ ['screen and (max-width: 640px)', {
39
+ seriesBarDistance: 5,
40
+ axisX: {
41
+ labelInterpolationFnc: function (value) {
42
+ return value[0];
43
+ }
40
44
  }
41
- }
42
- }]
43
- ];
45
+ }]
46
+ ];
44
47
 
45
- new Chartist.Bar("##{id}", {
46
- labels: labels,
47
- series: series
48
- },
49
- options,
50
- responsiveOptions
51
- );
48
+ new Chartist.Bar("##{id}", {
49
+ labels: labels,
50
+ series: series
51
+ },
52
+ options,
53
+ responsiveOptions
54
+ );
52
55
 
53
- css:
54
- ##{{id}} .ct-bar {
55
- stroke-width: #{{100/(labels.count*series.count)}}%
56
- }
56
+ css:
57
+ ##{{id}} .ct-bar {
58
+ stroke-width: #{{100/(labels.count*series.count)}}%
59
+ }
@@ -9,6 +9,10 @@
9
9
  tr
10
10
  -for element in serie
11
11
  td #{element}
12
+ tr
13
+ -total = [1,serie.reduce(:+)].max
14
+ -for element in serie
15
+ td #{(element.to_f*100/total).round(0)}%
12
16
 
13
17
  javascript:
14
18
  var labels = #{{labels}};
@@ -25,7 +29,7 @@ javascript:
25
29
  Chartist.plugins.legend()
26
30
  ]
27
31
  }
28
- );
32
+ );
29
33
 
30
34
  css:
31
35
  .pie .ct-legend.ct-legend-inside {
@@ -18,8 +18,8 @@ javascript:
18
18
  var series = #{{series}};
19
19
 
20
20
  new Chartist.Bar("##{id}", {
21
- labels: labels,
22
- series: series
21
+ labels: labels,
22
+ series: series
23
23
  }, {
24
24
  stackBars: true,
25
25
  axisY: {
@@ -0,0 +1,59 @@
1
+ .block-header
2
+ h2
3
+ | Constantes
4
+
5
+ -grouped_constants = constants.group_by { |constant| constant.kind }
6
+ -for kind in grouped_constants.keys
7
+ .card.m-b-5
8
+ .card-header style="padding: 20px;"
9
+ .media
10
+ .media-body.m-t-0
11
+ .row
12
+ .col-md-3
13
+ h2
14
+ small.m-0 Tipo de constante
15
+ h5.m-0 #{grouped_constants[kind].first.name}
16
+ small.m-0 #{grouped_constants[kind].count} valores
17
+ .col-md-9
18
+ -for constant in grouped_constants[kind]
19
+ a.btn.btn-link.bgm-lightgray.m-5.c-gray onclick="editConstant(#{constant.id},'#{constant.kind}','#{constant.value}')"
20
+ .di-block.v-middle #{constant.value}
21
+
22
+ .footer-text
23
+ a.text.btn.bgm-white.c-gray data-toggle="modal" data-target="#new-constant" Nueva constante
24
+
25
+ a.btn.btn-float.bgm-blue.m-btn.waves-effect.waves-circle.waves-float data-toggle="modal" data-target="#new-constant"
26
+ i.zmdi.zmdi-plus
27
+
28
+ == slim :'sinatra-hexacta/constants/new'
29
+
30
+
31
+ .modal.fade id="edit-constant" tabindex="-1" role="dialog" aria-labelledby="editConstant"
32
+ .modal-dialog
33
+ form.modal-content method="POST" data-toggle="validator"
34
+ .modal-content
35
+ .modal-header
36
+ h4.modal-title Editar constante
37
+ .modal-body
38
+ .row
39
+ .col-sm-12
40
+ == select_input({ :id => 'edit_kind', :name => "kind", :elements => [{ :value => nil, :text => 'Elige tipo de constante' }] + (Constant.descendants).collect { |constant_class| { :value => constant_class, :text => constant_class.new.name } }.uniq, :placeholder => "Tipo de constante", :chosen => nil, :required => true })
41
+ .col-sm-12
42
+ == input({ :id => 'edit_value', :name => "value", :title => "Valor", :type => 'text', :value => nil, :required => true })
43
+ .modal-footer
44
+ a.btn.waves-effect.bgm-red#delete.pull-left.c-white Borrar
45
+ button.btn.btn-link.waves-effect data-dismiss="modal" type="button" Cerrar
46
+ button.btn.btn-link.waves-effect type="submit" Actualizar
47
+
48
+
49
+ javascript:
50
+ function editConstant(constant_id,kind,value) {
51
+ $('#edit-constant .action').attr('action', '/constants/' + constant_id);
52
+
53
+ $('#edit-constant #edit_kind').val(kind);
54
+ $('#edit-constant #edit_value').val(value);
55
+
56
+ $('#edit-constant #edit_kind').trigger("chosen:updated");
57
+ $('#edit-constant #delete').attr("onclick","rm_object('constants','"+ constant_id +"')");
58
+ $('#edit-constant').modal('show');
59
+ }
@@ -0,0 +1,35 @@
1
+ .modal.fade id="new-constant" tabindex="-1" role="dialog" aria-labelledby="newConstant"
2
+ .modal-dialog.modal-lg
3
+ .row
4
+ .col-xs-4
5
+ form.modal-content action="/constant" method="POST" data-toggle="validator"
6
+ .modal-content
7
+ .modal-header
8
+ h4.modal-title Nueva constante
9
+ .modal-body
10
+ .row
11
+ .col-sm-12
12
+ == select_input({ :name => "kind", :elements => [{ :value => nil, :text => 'Elige tipo de constante' }] + (Constant.descendants).collect { |constant_class| { :value => constant_class, :text => constant_class.new.name } }.uniq, :placeholder => "Tipo de constante", :selected_elements => nil, :required => true })
13
+ .col-sm-12
14
+ == input({:name => "value", :title => "Valor", :type => 'text', :value => '', :required => true })
15
+ .modal-footer
16
+ button.btn.btn-link.waves-effect data-dismiss="modal" type="button" Cerrar
17
+ button.btn.btn-link.waves-effect type="submit" Crear
18
+
19
+ .col-xs-8
20
+ form.modal-content action="/constant" method="POST" data-toggle="validator"
21
+ .modal-content
22
+ .modal-header
23
+ h4.modal-title Nuevas constantes
24
+ .modal-body
25
+ .row
26
+ .col-sm-12
27
+ == select_input({ :name => "kind", :elements => [{ :value => nil, :text => 'Elige tipo de constante' }] + (Constant.descendants).collect { |constant_class| { :value => constant_class, :text => constant_class.new.name } }.uniq, :placeholder => "Tipo de constante", :selected_elements => nil, :required => true })
28
+ .col-sm-12
29
+ == input({:name => "values", :title => "Valores separados por coma", :type => 'text', :value => '', :required => true })
30
+ .modal-footer
31
+ button.btn.btn-link.waves-effect data-dismiss="modal" type="button" Cerrar
32
+ button.btn.btn-link.waves-effect type="submit" Crear
33
+ br
34
+ .modal-content
35
+ == slim info_alert({ :title => 'Creación masiva', :message => "Separa por coma los valores para crear multiples constantes de una sola vez."})
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra-hexacta
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.12
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Zanger
@@ -83,6 +83,7 @@ files:
83
83
  - lib/sinatra/extensions/menu.rb
84
84
  - lib/sinatra/extensions/notification.rb
85
85
  - lib/sinatra/extensions/processmanager.rb
86
+ - lib/sinatra/handlers/constants.rb
86
87
  - lib/sinatra/handlers/errors.rb
87
88
  - lib/sinatra/handlers/init.rb
88
89
  - lib/sinatra/handlers/notifications.rb
@@ -163,7 +164,6 @@ files:
163
164
  - lib/sinatra/public/vendors/malihu-custom-scrollbar-plugin/mCSB_buttons.png
164
165
  - lib/sinatra/public/vendors/material-design-iconic-font/css/material-design-iconic-font.css
165
166
  - lib/sinatra/public/vendors/material-design-iconic-font/css/material-design-iconic-font.min.css
166
- - lib/sinatra/public/vendors/material-design-iconic-font/fonts/Material-Design-Iconic-Font.eot
167
167
  - lib/sinatra/public/vendors/material-design-iconic-font/fonts/Material-Design-Iconic-Font.svg
168
168
  - lib/sinatra/public/vendors/material-design-iconic-font/fonts/Material-Design-Iconic-Font.ttf
169
169
  - lib/sinatra/public/vendors/material-design-iconic-font/fonts/Material-Design-Iconic-Font.woff
@@ -186,6 +186,8 @@ files:
186
186
  - lib/sinatra/views/charts/line.slim
187
187
  - lib/sinatra/views/charts/pie.slim
188
188
  - lib/sinatra/views/charts/stacked_bar.slim
189
+ - lib/sinatra/views/constants/group.slim
190
+ - lib/sinatra/views/constants/new.slim
189
191
  - lib/sinatra/views/errors/403.slim
190
192
  - lib/sinatra/views/errors/404.slim
191
193
  - lib/sinatra/views/errors/500.slim