sinatra-hexacta 0.1.1 → 0.3.4
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 +4 -4
- data/lib/sinatra/extensions/generalmail.rb +26 -0
- data/lib/sinatra/extensions/generalmailnolink.rb +24 -0
- data/lib/sinatra/extensions/init.rb +4 -0
- data/lib/sinatra/extensions/mail.rb +35 -0
- data/lib/sinatra/extensions/mailbuilder.rb +47 -0
- data/lib/sinatra/extensions/mailsender.rb +88 -0
- data/lib/sinatra/extensions/notification.rb +8 -5
- data/lib/sinatra/handlers/errors.rb +2 -2
- data/lib/sinatra/handlers/notifications.rb +4 -4
- data/lib/sinatra/handlers/reports.rb +1 -1
- data/lib/sinatra/helpers/alerts.rb +1 -1
- data/lib/sinatra/helpers/charts.rb +1 -1
- data/lib/sinatra/helpers/inputs.rb +1 -1
- data/lib/sinatra/helpers/libraries.rb +1 -1
- data/lib/sinatra/helpers/reports.rb +1 -1
- data/lib/sinatra/helpers/schedule.rb +2 -2
- data/lib/sinatra/hexacta.rb +12 -14
- data/lib/sinatra/public/js/app.js +33 -181
- data/lib/sinatra/views/inputs/input.slim +4 -3
- data/lib/sinatra/views/inputs/textarea.slim +4 -2
- data/lib/sinatra/views/notifications/form.slim +2 -0
- metadata +50 -4
- data/lib/sinatra/helpers/mailer.rb +0 -74
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 486d724d40440586e2c909583687a5aa34f9d4f348ff6d56cd6d35085f5ab9fb
|
4
|
+
data.tar.gz: d0ed9a2ded7adcc993e4e4cdbeed68938793e7da4b3510c108ec66222af94844
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd96c1d6eef238d9c1a929c0339483c9ee9e934b2bed2399fffe776543506ae930c700898a16bade0df3ca4e8672fa57cc8a14b0be6393fde0bc2b4d5e46bc9a
|
7
|
+
data.tar.gz: 0726a9d33be03576cceab798ad59aae29e8df592929ad89150d5827c3c8d35a8e1d2b5ac368c156e064a3bec475b64f0b17e3894f5e89779fd46b166c5e69b7a
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class GeneralMail < Mail
|
3
|
+
|
4
|
+
def initialize(args)
|
5
|
+
super(args)
|
6
|
+
@subject = args[:subject]
|
7
|
+
@description = args[:description]
|
8
|
+
@link = args[:link]
|
9
|
+
end
|
10
|
+
|
11
|
+
def template
|
12
|
+
'general'
|
13
|
+
end
|
14
|
+
|
15
|
+
def subject
|
16
|
+
@subject
|
17
|
+
end
|
18
|
+
|
19
|
+
def values
|
20
|
+
data = {}
|
21
|
+
data["{description}"] = @description
|
22
|
+
data["{link}"] = @link
|
23
|
+
data
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class GeneralMailNoLink < Mail
|
3
|
+
|
4
|
+
def initialize(args)
|
5
|
+
super(args)
|
6
|
+
@subject = args[:subject]
|
7
|
+
@description = args[:description]
|
8
|
+
end
|
9
|
+
|
10
|
+
def template
|
11
|
+
'general_no_link'
|
12
|
+
end
|
13
|
+
|
14
|
+
def subject
|
15
|
+
@subject
|
16
|
+
end
|
17
|
+
|
18
|
+
def values
|
19
|
+
data = {}
|
20
|
+
data["{description}"] = @description
|
21
|
+
data
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class Mail
|
3
|
+
|
4
|
+
def initialize(args)
|
5
|
+
@receivers = args[:to]
|
6
|
+
@sender = args[:from]
|
7
|
+
end
|
8
|
+
|
9
|
+
def template
|
10
|
+
raise Exception, "You have to override 'template' method in #{self.class}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def subject
|
14
|
+
raise Exception, "You have to override 'subject' method in #{self.class}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def values
|
18
|
+
raise Exception, "You have to override 'values' method in #{self.class}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def to
|
22
|
+
_receivers = {}
|
23
|
+
@receivers.each { |user| _receivers[user.full_name] = "Persons" }
|
24
|
+
_receivers
|
25
|
+
end
|
26
|
+
|
27
|
+
def from
|
28
|
+
@sender ||= "apps@hexacta.com"
|
29
|
+
end
|
30
|
+
|
31
|
+
def send
|
32
|
+
MailSender.perform_async(self)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class MailBuilder
|
3
|
+
|
4
|
+
def to(receivers)
|
5
|
+
@to = receivers
|
6
|
+
return self
|
7
|
+
end
|
8
|
+
|
9
|
+
def from(sender)
|
10
|
+
@from = "#{sender.hxt_id}@hexacta.com"
|
11
|
+
return self
|
12
|
+
end
|
13
|
+
|
14
|
+
def subject(a_subject)
|
15
|
+
@subject = a_subject
|
16
|
+
return self
|
17
|
+
end
|
18
|
+
|
19
|
+
def description(a_description)
|
20
|
+
@description = a_description
|
21
|
+
return self
|
22
|
+
end
|
23
|
+
|
24
|
+
def link(a_link)
|
25
|
+
@link = a_link
|
26
|
+
return self
|
27
|
+
end
|
28
|
+
|
29
|
+
def send
|
30
|
+
@from ||= "apps@hexacta.com"
|
31
|
+
if @link.nil?
|
32
|
+
GeneralMailNoLink.new({ :to => @to,
|
33
|
+
:from => @from,
|
34
|
+
:subject => @subject,
|
35
|
+
:description => @description
|
36
|
+
}).send
|
37
|
+
else
|
38
|
+
GeneralMail.new({ :to => @to,
|
39
|
+
:from => @from,
|
40
|
+
:subject => @subject,
|
41
|
+
:description => @description,
|
42
|
+
:link => @link
|
43
|
+
}).send
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'singleton'
|
3
|
+
require 'sucker_punch'
|
4
|
+
|
5
|
+
class MailSender
|
6
|
+
include SuckerPunch::Job
|
7
|
+
|
8
|
+
attr_reader :access_token, :expire, :refresh_token
|
9
|
+
|
10
|
+
def _do_connect(uri, form={},token=nil)
|
11
|
+
url = URI.parse("#{uri}")
|
12
|
+
http = Net::HTTP.new(url.host, url.port)
|
13
|
+
http.read_timeout = 1000
|
14
|
+
http.use_ssl = (url.scheme == 'https')
|
15
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
16
|
+
header = { 'Content-Type' => 'application/x-www-form-urlencoded' }
|
17
|
+
header["Authorization"] = "Bearer #{token}" unless token.nil?
|
18
|
+
request = Net::HTTP::Post.new(url, header)
|
19
|
+
request.form_data = form
|
20
|
+
http.start { |http| http.request(request) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def _authorize_mail
|
24
|
+
params = [ [ "grant_type", "password" ], [ "client_id", "MailApp" ], [ "client_secret", "MailAppPRD2018!" ] ]
|
25
|
+
response = _do_connect("https://comunicacion.hexacta.com:4443/apptoken",params)
|
26
|
+
if( response.is_a?( Net::HTTPSuccess ) )
|
27
|
+
token = JSON.parse(response.body)
|
28
|
+
@access_token = token["access_token"]
|
29
|
+
@refresh_token = token["refresh_token"]
|
30
|
+
@expire = DateTime.parse(token[".expires"])
|
31
|
+
else
|
32
|
+
NotificationSender.instance.send_error(nil,'Authorize mail failed',response.body)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def _build_map_values(mail_values)
|
37
|
+
values = []
|
38
|
+
for key in mail_values.keys
|
39
|
+
index = mail_values.keys.index(key)
|
40
|
+
values << ["MailValues[#{index}].Key", key]
|
41
|
+
values << ["MailValues[#{index}].Value", mail_values[key]]
|
42
|
+
end
|
43
|
+
values
|
44
|
+
end
|
45
|
+
|
46
|
+
def _build_to_map(to_map)
|
47
|
+
values = []
|
48
|
+
for key in to_map.keys
|
49
|
+
index = to_map.keys.index(key)
|
50
|
+
values << ["ResourcesRequest[#{index}].TypeGroup", to_map[key]]
|
51
|
+
values << ["ResourcesRequest[#{index}].Name", key]
|
52
|
+
end
|
53
|
+
values
|
54
|
+
end
|
55
|
+
|
56
|
+
def _expired?
|
57
|
+
expire.nil? || DateTime.now < expire
|
58
|
+
end
|
59
|
+
|
60
|
+
def do_send(mail)
|
61
|
+
begin
|
62
|
+
if _expired?
|
63
|
+
_authorize_mail
|
64
|
+
end
|
65
|
+
|
66
|
+
params = [ [ "ApplicationCode", 2009 ], [ "Name", mail.template ], [ "Subject", mail.subject ], [ "EmailAddress", mail.from ] ]
|
67
|
+
params = params + _build_map_values(mail.values) + _build_to_map(mail.to)
|
68
|
+
|
69
|
+
response = _do_connect("https://comunicacion.hexacta.com:4444/api/app/TemplateNotification/SendMail",params,@access_token)
|
70
|
+
|
71
|
+
if( !response.is_a?( Net::HTTPSuccess ) )
|
72
|
+
NotificationSender.instance.send_error(nil,'Send mail failed',response.body)
|
73
|
+
end
|
74
|
+
rescue StandardError => error
|
75
|
+
message = error.backtrace.join(',');
|
76
|
+
NotificationSender.instance.send_error(nil,"Mail send error",message)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def send(mail)
|
81
|
+
run(mail) #Async call
|
82
|
+
end
|
83
|
+
|
84
|
+
#For async method call
|
85
|
+
def perform(mail)
|
86
|
+
do_send(mail)
|
87
|
+
end
|
88
|
+
end
|
@@ -1,7 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require 'singleton'
|
3
|
+
|
2
4
|
class NotificationSender
|
5
|
+
include Singleton
|
3
6
|
|
4
|
-
def
|
7
|
+
def send_to(user,creator,title,message,label,link=nil)
|
5
8
|
notification = Notification.find_or_create(:user_id => user.id,
|
6
9
|
:creator_id => creator.id,
|
7
10
|
:title => title,
|
@@ -16,13 +19,13 @@ class NotificationSender
|
|
16
19
|
notification
|
17
20
|
end
|
18
21
|
|
19
|
-
def
|
22
|
+
def send_to_subscriptors(creator,title,message,label,link=nil)
|
20
23
|
Subscription.where(:label => label).all.each do |subscription|
|
21
|
-
notification =
|
24
|
+
notification = send_to(subscription.user,creator,title,message,label,link)
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
25
|
-
def
|
28
|
+
def send_error(creator,title,message)
|
26
29
|
Subscription.where(:label => 'error').all.each do |subscription|
|
27
30
|
creator = subscription.user if creator.nil?
|
28
31
|
notification = Notification.find(:user_id => subscription.user_id,
|
@@ -32,7 +35,7 @@ class NotificationSender
|
|
32
35
|
:label => 'error',
|
33
36
|
:read_date => nil)
|
34
37
|
if notification.nil?
|
35
|
-
notification =
|
38
|
+
notification = send_to(subscription.user,creator,title,message,'error')
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
@@ -13,12 +13,12 @@ module Sinatra
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def error_template(code)
|
16
|
-
ErrorHandler.
|
16
|
+
ErrorHandler.copy_file("/lib/sinatra/views/errors/#{code}.slim","/app/views/#{Hexacta::GEM_FILE_DIR}/errors/#{code}.slim")
|
17
17
|
error code do
|
18
18
|
if code == 500
|
19
19
|
title = env['sinatra.error'].message.split(':')[0].gsub('#<','');
|
20
20
|
message = (["in #{request.url}"] + env['sinatra.error'].backtrace).join(',');
|
21
|
-
NotificationSender.send_error(authenticated(User),title,message)
|
21
|
+
NotificationSender.instance.send_error(authenticated(User),title,message)
|
22
22
|
end
|
23
23
|
slim "#{Hexacta::GEM_FILE_DIR}/errors/#{code}".to_sym, locals: { :params => params }
|
24
24
|
end
|
@@ -6,15 +6,15 @@ module Sinatra
|
|
6
6
|
def enable_notifications
|
7
7
|
p "Enabling notifications..."
|
8
8
|
NotificationHandler.setup_dir("/app/views/#{Hexacta::GEM_FILE_DIR}/notifications")
|
9
|
-
NotificationHandler.
|
10
|
-
NotificationHandler.
|
9
|
+
NotificationHandler.copy_file("/lib/sinatra/views/notifications.slim","/app/views/#{Hexacta::GEM_FILE_DIR}/notifications.slim")
|
10
|
+
NotificationHandler.copy_all_files("/lib/sinatra/views/notifications","/app/views/#{Hexacta::GEM_FILE_DIR}/notifications")
|
11
11
|
|
12
12
|
post '/notification' do
|
13
13
|
if params[:user_ids].blank?
|
14
|
-
NotificationSender.send_to_subscriptors(authenticated(User),params[:title],params[:message],params[:label])
|
14
|
+
NotificationSender.instance.send_to_subscriptors(authenticated(User),params[:title],params[:message],params[:label])
|
15
15
|
else
|
16
16
|
for id in params[:user_ids]
|
17
|
-
NotificationSender.send_to(User.find(:id => id),authenticated(User),params[:title],params[:message],params[:label])
|
17
|
+
NotificationSender.instance.send_to(User.find(:id => id),authenticated(User),params[:title],params[:message],params[:label])
|
18
18
|
end
|
19
19
|
end
|
20
20
|
redirect back
|
@@ -14,7 +14,7 @@ module Sinatra
|
|
14
14
|
end
|
15
15
|
|
16
16
|
get '/reports/:report_name' do |report_name|
|
17
|
-
date = Date.parse(params[
|
17
|
+
date = Date.parse(params[:date]) unless params[:date].nil?
|
18
18
|
date ||= Date.today
|
19
19
|
headers "Content-Disposition" => "attachment;filename=#{report_name}.#{date}.xls",
|
20
20
|
"Content-Type" => "application/octet-stream"
|
@@ -20,7 +20,7 @@ module Sinatra
|
|
20
20
|
end
|
21
21
|
|
22
22
|
setup_dir("/app/views/#{Hexacta::GEM_FILE_DIR}/alerts")
|
23
|
-
|
23
|
+
copy_all_files("/lib/sinatra/views/alerts","/app/views/#{Hexacta::GEM_FILE_DIR}/alerts")
|
24
24
|
end
|
25
25
|
|
26
26
|
helpers AlertHelper
|
@@ -24,7 +24,7 @@ module Sinatra
|
|
24
24
|
end
|
25
25
|
|
26
26
|
setup_dir("/app/views/#{Hexacta::GEM_FILE_DIR}/charts")
|
27
|
-
|
27
|
+
copy_all_files("/lib/sinatra/views/charts","/app/views/#{Hexacta::GEM_FILE_DIR}/charts")
|
28
28
|
end
|
29
29
|
|
30
30
|
helpers ChartsHelper
|
@@ -40,7 +40,7 @@ module Sinatra
|
|
40
40
|
end
|
41
41
|
|
42
42
|
setup_dir("/app/views/#{Hexacta::GEM_FILE_DIR}/inputs")
|
43
|
-
|
43
|
+
copy_all_files("/lib/sinatra/views/inputs","/app/views/#{Hexacta::GEM_FILE_DIR}/inputs")
|
44
44
|
end
|
45
45
|
|
46
46
|
helpers InputHelper
|
@@ -18,7 +18,7 @@ module Sinatra
|
|
18
18
|
p "Setting up libraries directory..."
|
19
19
|
copy_dir_structure("/lib/sinatra/public","/app/public/#{Hexacta::GEM_FILE_DIR}")
|
20
20
|
setup_dir("/app/views/#{Hexacta::GEM_FILE_DIR}/libraries")
|
21
|
-
|
21
|
+
copy_all_files("/lib/sinatra/views/libraries","/app/views/#{Hexacta::GEM_FILE_DIR}/libraries")
|
22
22
|
end
|
23
23
|
|
24
24
|
helpers LibrariesHelper
|
@@ -20,7 +20,7 @@ module Sinatra
|
|
20
20
|
end
|
21
21
|
|
22
22
|
setup_dir("/app/views/#{Hexacta::GEM_FILE_DIR}/reports")
|
23
|
-
|
23
|
+
copy_all_files("/lib/sinatra/views/reports","/app/views/#{Hexacta::GEM_FILE_DIR}/reports")
|
24
24
|
end
|
25
25
|
|
26
26
|
helpers ReportHelper
|
@@ -21,7 +21,7 @@ module Sinatra
|
|
21
21
|
rescue StandardError => error
|
22
22
|
title = error.message.split(':')[0].gsub('#<','');
|
23
23
|
message = error.backtrace.join(',');
|
24
|
-
NotificationSender.send_error(nil,title,message)
|
24
|
+
NotificationSender.instance.send_error(nil,title,message)
|
25
25
|
end
|
26
26
|
|
27
27
|
end
|
@@ -50,7 +50,7 @@ module Sinatra
|
|
50
50
|
rescue error
|
51
51
|
title = error.message.split(':')[0].gsub('#<','');
|
52
52
|
message = error.backtrace.join(',');
|
53
|
-
NotificationSender.send_error(nil,title,message)
|
53
|
+
NotificationSender.instance.send_error(nil,title,message)
|
54
54
|
end
|
55
55
|
|
56
56
|
end
|
data/lib/sinatra/hexacta.rb
CHANGED
@@ -9,28 +9,26 @@ module Sinatra
|
|
9
9
|
module Hexacta
|
10
10
|
GEM_FILE_DIR = "sinatra-hexacta"
|
11
11
|
|
12
|
-
def
|
13
|
-
File.
|
12
|
+
def gem_path
|
13
|
+
File.expand_path("../..",__dir__)
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
|
18
|
-
symlink("#{original_path}/#{child}","#{link_path}/#{child}") unless child == '.' || child == '..'
|
19
|
-
end unless Gem.loaded_specs["sinatra-hexacta"].nil?
|
16
|
+
def copy_file(original_path, link_path)
|
17
|
+
IO.copy_stream("#{gem_path}#{original_path}",link_path) unless File.exist?(link_path) && FileUtils.compare_file("#{gem_path}#{original_path}",link_path)
|
20
18
|
end
|
21
19
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
FileUtils.mkdir_p path
|
20
|
+
def copy_all_files(original_path, link_path)
|
21
|
+
Dir.foreach("#{gem_path}#{original_path}") do |child|
|
22
|
+
copy_file("#{original_path}/#{child}","#{link_path}/#{child}") unless child == '.' || child == '..'
|
26
23
|
end
|
27
24
|
end
|
28
25
|
|
26
|
+
def setup_dir(path)
|
27
|
+
FileUtils.mkdir_p path
|
28
|
+
end
|
29
|
+
|
29
30
|
def copy_dir_structure(original_path, destination_path)
|
30
|
-
|
31
|
-
FileUtils.remove_dir destination_path if Dir.exist? destination_path
|
32
|
-
FileUtils.copy_entry("#{Gem.loaded_specs["sinatra-hexacta"].gem_dir}#{original_path}", destination_path)
|
33
|
-
end
|
31
|
+
FileUtils.copy_entry("#{gem_path}#{original_path}", destination_path)
|
34
32
|
end
|
35
33
|
end
|
36
34
|
end
|
@@ -39,6 +39,7 @@ $(document).ready(function(){
|
|
39
39
|
$(this).find('#submit').attr('disabled','disabled');
|
40
40
|
}
|
41
41
|
});
|
42
|
+
|
42
43
|
$('.chosen[required]').on('change', function(change, deselected) { //selected OR deselected
|
43
44
|
if ($(this).val() == "" || $(this).val() == null) {
|
44
45
|
$(this).parent().removeClass("success");
|
@@ -48,36 +49,6 @@ $(document).ready(function(){
|
|
48
49
|
$(this).parent().addClass("success");
|
49
50
|
}
|
50
51
|
});
|
51
|
-
/* --------------------------------------------------------
|
52
|
-
Layout
|
53
|
-
-----------------------------------------------------------*/
|
54
|
-
(function () {
|
55
|
-
|
56
|
-
//Get saved layout type from LocalStorage
|
57
|
-
var layoutStatus = localStorage.getItem('ma-layout-status');
|
58
|
-
$('#header').attr('data-current-skin', "pink");
|
59
|
-
if(!$('#header-2')[0]) { //Make it work only on normal headers
|
60
|
-
if (layoutStatus == 1) {
|
61
|
-
$('body').addClass('sw-toggled');
|
62
|
-
$('#tw-switch').prop('checked', true);
|
63
|
-
}
|
64
|
-
}
|
65
|
-
|
66
|
-
$('body').on('change', '#toggle-width input:checkbox', function () {
|
67
|
-
if ($(this).is(':checked')) {
|
68
|
-
setTimeout(function () {
|
69
|
-
$('body').addClass('toggled sw-toggled');
|
70
|
-
localStorage.setItem('ma-layout-status', 1);
|
71
|
-
}, 250);
|
72
|
-
}
|
73
|
-
else {
|
74
|
-
setTimeout(function () {
|
75
|
-
$('body').removeClass('toggled sw-toggled');
|
76
|
-
localStorage.setItem('ma-layout-status', 0);
|
77
|
-
}, 250);
|
78
|
-
}
|
79
|
-
});
|
80
|
-
})();
|
81
52
|
|
82
53
|
//Hack for modal to work on dropdown menu
|
83
54
|
$('header .lv-item').click(function(e) {
|
@@ -110,30 +81,12 @@ $(document).ready(function(){
|
|
110
81
|
}
|
111
82
|
}
|
112
83
|
|
113
|
-
/*
|
114
|
-
* Top Search
|
115
|
-
*/
|
116
|
-
(function(){
|
117
|
-
$('body').on('click', '#top-search > a', function(e){
|
118
|
-
e.preventDefault();
|
119
|
-
|
120
|
-
$('#header').addClass('search-toggled');
|
121
|
-
$('#top-search-wrap input').focus();
|
122
|
-
});
|
123
|
-
|
124
|
-
$('body').on('click', '#top-search-close', function(e){
|
125
|
-
e.preventDefault();
|
126
|
-
|
127
|
-
$('#header').removeClass('search-toggled');
|
128
|
-
});
|
129
|
-
})();
|
130
|
-
|
131
84
|
/*
|
132
85
|
* Sidebar
|
133
86
|
*/
|
134
87
|
(function(){
|
135
88
|
//Toggle
|
136
|
-
$('body').on('click', '#menu-trigger
|
89
|
+
$('body').on('click', '#menu-trigger', function(e){
|
137
90
|
e.preventDefault();
|
138
91
|
var x = $(this).data('trigger');
|
139
92
|
|
@@ -146,58 +99,42 @@ $(document).ready(function(){
|
|
146
99
|
$(this).find('ul').hide();
|
147
100
|
});
|
148
101
|
|
102
|
+
$('.profile-menu .main-menu').hide();
|
149
103
|
|
104
|
+
if (x == '#sidebar') {
|
150
105
|
|
151
|
-
|
152
|
-
|
153
|
-
if (x == '#sidebar') {
|
154
|
-
|
155
|
-
$elem = '#sidebar';
|
156
|
-
$elem2 = '#menu-trigger';
|
157
|
-
|
158
|
-
$('#chat-trigger').removeClass('open');
|
159
|
-
|
160
|
-
if (!$('#chat').hasClass('toggled')) {
|
161
|
-
$('#header').toggleClass('sidebar-toggled');
|
162
|
-
}
|
163
|
-
else {
|
164
|
-
$('#chat').removeClass('toggled');
|
165
|
-
}
|
166
|
-
}
|
106
|
+
$elem = '#sidebar';
|
107
|
+
$elem2 = '#menu-trigger';
|
167
108
|
|
168
|
-
|
169
|
-
$elem = '#chat';
|
170
|
-
$elem2 = '#chat-trigger';
|
109
|
+
$('#chat-trigger').removeClass('open');
|
171
110
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
}
|
180
|
-
}
|
111
|
+
if (!$('#chat').hasClass('toggled')) {
|
112
|
+
$('#header').toggleClass('sidebar-toggled');
|
113
|
+
}
|
114
|
+
else {
|
115
|
+
$('#chat').removeClass('toggled');
|
116
|
+
}
|
117
|
+
}
|
181
118
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
119
|
+
//When clicking outside
|
120
|
+
if ($('#header').hasClass('sidebar-toggled')) {
|
121
|
+
$(document).on('click', function (e) {
|
122
|
+
if (($(e.target).closest($elem).length === 0) && ($(e.target).closest($elem2).length === 0)) {
|
123
|
+
setTimeout(function(){
|
124
|
+
$($elem).removeClass('toggled');
|
125
|
+
$('#header').removeClass('sidebar-toggled');
|
126
|
+
$($elem2).removeClass('open');
|
127
|
+
});
|
128
|
+
}
|
129
|
+
});
|
130
|
+
}
|
194
131
|
})
|
195
132
|
|
196
133
|
//Submenu
|
197
134
|
$('body').on('click', '.sub-menu > a', function(e){
|
198
|
-
|
199
|
-
|
200
|
-
|
135
|
+
e.preventDefault();
|
136
|
+
$(this).next().slideToggle(200);
|
137
|
+
$(this).parent().toggleClass('toggled');
|
201
138
|
});
|
202
139
|
})();
|
203
140
|
|
@@ -229,7 +166,7 @@ $(document).ready(function(){
|
|
229
166
|
|
230
167
|
//Popup empty message
|
231
168
|
setTimeout(function(){
|
232
|
-
|
169
|
+
$('#notifications').addClass('empty');
|
233
170
|
}, (z*150)+200);
|
234
171
|
});
|
235
172
|
|
@@ -380,9 +317,9 @@ $(document).ready(function(){
|
|
380
317
|
* Waves Animation
|
381
318
|
*/
|
382
319
|
(function(){
|
383
|
-
|
384
|
-
|
385
|
-
|
320
|
+
Waves.attach('.btn:not(.btn-icon):not(.btn-float)');
|
321
|
+
Waves.attach('.btn-icon, .btn-float', ['waves-circle', 'waves-float']);
|
322
|
+
Waves.init();
|
386
323
|
})();
|
387
324
|
|
388
325
|
/*
|
@@ -462,87 +399,6 @@ $(document).ready(function(){
|
|
462
399
|
});
|
463
400
|
}
|
464
401
|
|
465
|
-
/*
|
466
|
-
* Login
|
467
|
-
*/
|
468
|
-
if ($('.login-content')[0]) {
|
469
|
-
//Add class to HTML. This is used to center align the logn box
|
470
|
-
$('html').addClass('login-content');
|
471
|
-
|
472
|
-
$('body').on('click', '.login-navigation > li', function(){
|
473
|
-
var z = $(this).data('block');
|
474
|
-
var t = $(this).closest('.lc-block');
|
475
|
-
|
476
|
-
t.removeClass('toggled');
|
477
|
-
|
478
|
-
setTimeout(function(){
|
479
|
-
$(z).addClass('toggled');
|
480
|
-
});
|
481
|
-
|
482
|
-
})
|
483
|
-
}
|
484
|
-
|
485
|
-
/*
|
486
|
-
* Fullscreen Browsing
|
487
|
-
*/
|
488
|
-
if ($('[data-action="fullscreen"]')[0]) {
|
489
|
-
var fs = $("[data-action='fullscreen']");
|
490
|
-
fs.on('click', function(e) {
|
491
|
-
e.preventDefault();
|
492
|
-
|
493
|
-
//Launch
|
494
|
-
function launchIntoFullscreen(element) {
|
495
|
-
if(element.requestFullscreen) {
|
496
|
-
element.requestFullscreen();
|
497
|
-
} else if(element.mozRequestFullScreen) {
|
498
|
-
element.mozRequestFullScreen();
|
499
|
-
} else if(element.webkitRequestFullscreen) {
|
500
|
-
element.webkitRequestFullscreen();
|
501
|
-
} else if(element.msRequestFullscreen) {
|
502
|
-
element.msRequestFullscreen();
|
503
|
-
}
|
504
|
-
}
|
505
|
-
|
506
|
-
//Exit
|
507
|
-
function exitFullscreen() {
|
508
|
-
if(document.exitFullscreen) {
|
509
|
-
document.exitFullscreen();
|
510
|
-
} else if(document.mozCancelFullScreen) {
|
511
|
-
document.mozCancelFullScreen();
|
512
|
-
} else if(document.webkitExitFullscreen) {
|
513
|
-
document.webkitExitFullscreen();
|
514
|
-
}
|
515
|
-
}
|
516
|
-
|
517
|
-
launchIntoFullscreen(document.documentElement);
|
518
|
-
fs.closest('.dropdown').removeClass('open');
|
519
|
-
});
|
520
|
-
}
|
521
|
-
|
522
|
-
/*
|
523
|
-
* Clear Local Storage
|
524
|
-
*/
|
525
|
-
if ($('[data-action="clear-localstorage"]')[0]) {
|
526
|
-
var cls = $('[data-action="clear-localstorage"]');
|
527
|
-
|
528
|
-
cls.on('click', function(e) {
|
529
|
-
e.preventDefault();
|
530
|
-
|
531
|
-
swal({
|
532
|
-
title: "¿Estás seguro?",
|
533
|
-
text: "Todos tus datos locales serán borrados.",
|
534
|
-
type: "warning",
|
535
|
-
showCancelButton: true,
|
536
|
-
confirmButtonColor: "#DD6B55",
|
537
|
-
confirmButtonText: "Borrar",
|
538
|
-
cancelButtonText: "Cancelar",
|
539
|
-
closeOnConfirm: false
|
540
|
-
}, function(){
|
541
|
-
localStorage.clear();
|
542
|
-
swal("Hecho!", "Cache borrada", "success");
|
543
|
-
});
|
544
|
-
});
|
545
|
-
}
|
546
402
|
|
547
403
|
/*
|
548
404
|
* Profile Edit Toggle
|
@@ -785,10 +641,6 @@ function advance_search(url,offset,format) {
|
|
785
641
|
}
|
786
642
|
};
|
787
643
|
|
788
|
-
$(document).ready(function(){
|
789
|
-
$( ".paginator" ).clone().appendTo( "#content" );
|
790
|
-
});
|
791
|
-
|
792
644
|
function read_notify(id,url) {
|
793
645
|
$.ajax({
|
794
646
|
url: '/notifications/' + id,
|
@@ -4,15 +4,16 @@
|
|
4
4
|
- id = "#{name}_#{rand(1000)}"
|
5
5
|
- unless defined? placeholder
|
6
6
|
- placeholder = "..."
|
7
|
-
|
7
|
+
-unless defined? onkeyup
|
8
|
+
-onkeyup = ''
|
8
9
|
|
9
10
|
-if required
|
10
11
|
.form-group.has-feedback.has-success
|
11
12
|
label #{title}
|
12
13
|
.fg-line
|
13
|
-
input.form-control.fg-input id="#{id}" type="#{type}" placeholder=("#{placeholder}") name="#{name}" required="" value="#{value}"
|
14
|
+
input.form-control.fg-input id="#{id}" type="#{type}" placeholder=("#{placeholder}") name="#{name}" required="" value="#{value}" onkeyup="#{onkeyup}"
|
14
15
|
-else
|
15
16
|
.form-group
|
16
17
|
label #{title}
|
17
18
|
.fg-line
|
18
|
-
input.form-control.fg-input id="#{id}" type="#{type}" placeholder=("#{placeholder}") name="#{name}" value="#{value}"
|
19
|
+
input.form-control.fg-input id="#{id}" type="#{type}" placeholder=("#{placeholder}") name="#{name}" value="#{value}" onkeyup="#{onkeyup}"
|
@@ -4,11 +4,13 @@
|
|
4
4
|
- id = "#{name}_#{rand(1000)}"
|
5
5
|
- unless defined? placeholder
|
6
6
|
- placeholder = "Escribe aquí..."
|
7
|
+
- unless defined? rows
|
8
|
+
- rows = 5
|
7
9
|
|
8
10
|
.form-group
|
9
11
|
.fg-line
|
10
12
|
label.fg-label #{title}
|
11
13
|
- if required
|
12
|
-
textarea.form-control name="#{name}" placeholder=("#{placeholder}") rows="
|
14
|
+
textarea.form-control name="#{name}" placeholder=("#{placeholder}") rows="#{rows}" maxlength="#{length}" required="" #{value}
|
13
15
|
- else
|
14
|
-
textarea.form-control name="#{name}" placeholder=("#{placeholder}") rows="
|
16
|
+
textarea.form-control name="#{name}" placeholder=("#{placeholder}") rows="#{rows}" maxlength="#{length}" #{value}
|
@@ -9,6 +9,8 @@
|
|
9
9
|
== multiple_select_input({ :name => "user_id", :elements => notifications.collect { |notification| { :value => notification.creator.id, :text => notification.creator.full_name } }.uniq, :placeholder => "Empleados", :selected_elements => filters[:user_id] })
|
10
10
|
.col-md-12
|
11
11
|
== multiple_select_input({ :name => "label", :elements => Notification.labels.collect { |notification| { :value => notification.label, :text => notification.label.upcase } }, :placeholder => "Etiquetas", :selected_elements => filters[:label] })
|
12
|
+
.col-md-12
|
13
|
+
== multiple_select_input({ :name => "status", :elements => Notification.labels.collect { |notification| { :value => notification.label, :text => notification.label.upcase } }, :placeholder => "Etiquetas", :selected_elements => filters[:label] })
|
12
14
|
.pm-body.clearfix
|
13
15
|
ul.tab-nav.tn-justified role="tablist"
|
14
16
|
li.waves-effect.active role="presentation"
|
metadata
CHANGED
@@ -1,15 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-hexacta
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marco Zanger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-06-
|
12
|
-
dependencies:
|
11
|
+
date: 2020-06-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: sucker_punch
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: tzinfo-data
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.2019'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.2019'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rufus-scheduler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.6.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.6.0
|
13
55
|
description: A gem to support general functionality accross all apps
|
14
56
|
email: mzanger@hexacta.com
|
15
57
|
executables: []
|
@@ -18,7 +60,12 @@ extra_rdoc_files: []
|
|
18
60
|
files:
|
19
61
|
- lib/sinatra/extensions/antiquity.rb
|
20
62
|
- lib/sinatra/extensions/date.rb
|
63
|
+
- lib/sinatra/extensions/generalmail.rb
|
64
|
+
- lib/sinatra/extensions/generalmailnolink.rb
|
21
65
|
- lib/sinatra/extensions/init.rb
|
66
|
+
- lib/sinatra/extensions/mail.rb
|
67
|
+
- lib/sinatra/extensions/mailbuilder.rb
|
68
|
+
- lib/sinatra/extensions/mailsender.rb
|
22
69
|
- lib/sinatra/extensions/notification.rb
|
23
70
|
- lib/sinatra/handlers/errors.rb
|
24
71
|
- lib/sinatra/handlers/init.rb
|
@@ -31,7 +78,6 @@ files:
|
|
31
78
|
- lib/sinatra/helpers/init.rb
|
32
79
|
- lib/sinatra/helpers/inputs.rb
|
33
80
|
- lib/sinatra/helpers/libraries.rb
|
34
|
-
- lib/sinatra/helpers/mailer.rb
|
35
81
|
- lib/sinatra/helpers/reports.rb
|
36
82
|
- lib/sinatra/helpers/schedule.rb
|
37
83
|
- lib/sinatra/helpers/subscriptions.rb
|
@@ -1,74 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'sucker_punch'
|
3
|
-
|
4
|
-
module Sinatra
|
5
|
-
module MailHelper
|
6
|
-
|
7
|
-
attr_reader :access_token, :expire, :refresh_token
|
8
|
-
|
9
|
-
def _do_connect(uri, form={},token=nil)
|
10
|
-
url = URI.parse("#{uri}")
|
11
|
-
http = Net::HTTP.new(url.host, url.port)
|
12
|
-
http.read_timeout = 1000
|
13
|
-
http.use_ssl = (url.scheme == 'https')
|
14
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
15
|
-
header = { 'Content-Type' => 'application/x-www-form-urlencoded' }
|
16
|
-
header["Authorization"] = "Bearer #{token}" unless token.nil?
|
17
|
-
request = Net::HTTP::Post.new(url, header)
|
18
|
-
request.form_data = form
|
19
|
-
http.start {|http| http.request(request) }
|
20
|
-
end
|
21
|
-
|
22
|
-
def _authorize_mail
|
23
|
-
params = [ [ "grant_type", "password" ], [ "client_id", "MailApp" ], [ "client_secret", "MailAppPRD2018!" ] ]
|
24
|
-
response = _do_connect("https://comunicacion.hexacta.com:4443/apptoken",params)
|
25
|
-
if( response.is_a?( Net::HTTPSuccess ) )
|
26
|
-
token = JSON.parse(response.body)
|
27
|
-
@access_token = token["access_token"]
|
28
|
-
@refresh_token = token["refresh_token"]
|
29
|
-
@expire = DateTime.parse(token[".expires"])
|
30
|
-
else
|
31
|
-
p "Didn't succeed :("
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def _build_map_values(mail_values)
|
36
|
-
values = []
|
37
|
-
for key in mail_values.keys
|
38
|
-
index = mail_values.keys.index(key)
|
39
|
-
values << ["MailValues[#{index}].Key", key]
|
40
|
-
values << ["MailValues[#{index}].Value", mail_values[key]]
|
41
|
-
end
|
42
|
-
values
|
43
|
-
end
|
44
|
-
|
45
|
-
def _build_to_map(to_map)
|
46
|
-
values = []
|
47
|
-
for key in to_map.keys
|
48
|
-
index = to_map.keys.index(key)
|
49
|
-
values << ["ResourcesRequest[#{index}].TypeGroup", to_map[key]]
|
50
|
-
values << ["ResourcesRequest[#{index}].Name", key]
|
51
|
-
end
|
52
|
-
values
|
53
|
-
end
|
54
|
-
|
55
|
-
def _expired?
|
56
|
-
expire.nil? || DateTime.now < expire
|
57
|
-
end
|
58
|
-
|
59
|
-
def send_mail(template,subject,mail_values={},to_map)
|
60
|
-
if _expired?
|
61
|
-
_authorize_mail
|
62
|
-
end
|
63
|
-
params = [ [ "ApplicationCode", 1 ], [ "Name", template ], [ "Subject", subject ], [ "EmailAddress", "apps@hexacta.com" ] ]
|
64
|
-
params = params + _build_map_values(mail_values) + _build_to_map(to_map)
|
65
|
-
response = do_connect("https://comunicacion.hexacta.com:4444/api/app/TemplateNotification/SendMail",params,@access_token)
|
66
|
-
if( !response.is_a?( Net::HTTPSuccess ) )
|
67
|
-
p "Didn't succeed :("
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
helpers MailHelper
|
74
|
-
end
|