sinatra-hexacta 0.1.1 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|