egov_utils 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +26 -0
- data/app/assets/config/egov_utils_manifest.js +2 -0
- data/app/assets/javascripts/egov_utils/application.js +23 -0
- data/app/assets/javascripts/egov_utils/eGovUtilities.coffee.erb +70 -0
- data/app/assets/javascripts/egov_utils/groups.js +2 -0
- data/app/assets/javascripts/egov_utils/roles.coffee.erb +56 -0
- data/app/assets/javascripts/egov_utils/setup_locale.coffee.erb +2 -0
- data/app/assets/javascripts/egov_utils/users.js +2 -0
- data/app/assets/stylesheets/egov_utils/application.scss +15 -0
- data/app/assets/stylesheets/egov_utils/groups.css +4 -0
- data/app/assets/stylesheets/egov_utils/roles.css +4 -0
- data/app/assets/stylesheets/egov_utils/users.css +4 -0
- data/app/attributes/egov_utils/district.rb +13 -0
- data/app/attributes/egov_utils/full_address.rb +17 -0
- data/app/attributes/egov_utils/region.rb +13 -0
- data/app/controllers/egov_utils/addresses_controller.rb +34 -0
- data/app/controllers/egov_utils/application_controller.rb +7 -0
- data/app/controllers/egov_utils/groups_controller.rb +27 -0
- data/app/controllers/egov_utils/roles_controller.rb +28 -0
- data/app/controllers/egov_utils/sessions_controller.rb +83 -0
- data/app/controllers/egov_utils/users_controller.rb +64 -0
- data/app/helpers/egov_utils/application_helper.rb +4 -0
- data/app/helpers/egov_utils/grid_helper.rb +40 -0
- data/app/helpers/egov_utils/groups_helper.rb +4 -0
- data/app/helpers/egov_utils/roles_helper.rb +4 -0
- data/app/helpers/egov_utils/users_helper.rb +4 -0
- data/app/jobs/egov_utils/application_job.rb +4 -0
- data/app/mailers/egov_utils/application_mailer.rb +6 -0
- data/app/models/ability.rb +17 -0
- data/app/models/egov_utils/address.rb +79 -0
- data/app/models/egov_utils/application_record.rb +5 -0
- data/app/models/egov_utils/audit_detail.rb_bac +28 -0
- data/app/models/egov_utils/audit_record.rb_bac +98 -0
- data/app/models/egov_utils/group.rb +26 -0
- data/app/models/egov_utils/person.rb +9 -0
- data/app/models/egov_utils/principal.rb +20 -0
- data/app/models/egov_utils/user.rb +108 -0
- data/app/schemas/egov_utils/address_schema.rb +30 -0
- data/app/validators/email_validator.rb +8 -0
- data/app/validators/ico_validator.rb +7 -0
- data/app/views/common/_grid.html.coffee +130 -0
- data/app/views/common/_modal.html.haml +11 -0
- data/app/views/egov_utils/addresses/_form.html.haml +51 -0
- data/app/views/egov_utils/people/_form.html.haml +3 -0
- data/app/views/egov_utils/roles/index.html.haml +29 -0
- data/app/views/egov_utils/sessions/new.html.haml +5 -0
- data/app/views/egov_utils/users/_form.html.haml +6 -0
- data/app/views/egov_utils/users/index.html.haml +62 -0
- data/app/views/egov_utils/users/new.html.haml +3 -0
- data/app/views/egov_utils/users/show.html.haml +1 -0
- data/app/views/errors/error_403.html.haml +1 -0
- data/app/views/layouts/egov_utils/_messages.html.haml +7 -0
- data/app/views/layouts/egov_utils/application.html.erb +14 -0
- data/config/kraj.csv +16 -0
- data/config/locales/cs.yml +80 -0
- data/config/okres.csv +79 -0
- data/config/routes.rb +21 -0
- data/db/migrate/20170313100505_create_egov_utils_addresses.rb +18 -0
- data/db/migrate/20170315134217_create_egov_utils_users.rb +16 -0
- data/db/migrate/20170513115712_create_egov_utils_audit_records.rb_bac +11 -0
- data/db/migrate/20170513120006_create_egov_utils_audit_details.rb_bac +13 -0
- data/db/migrate/20170630150633_add_provider_to_user.rb +5 -0
- data/db/migrate/20170801154511_install_audited.rb +30 -0
- data/db/migrate/20170809150646_create_egov_utils_people.rb +12 -0
- data/db/migrate/20170824111701_create_egov_utils_groups.rb +12 -0
- data/lib/bootstrap_form/datetimepicker.rb +17 -0
- data/lib/bootstrap_form/helpers/bootstrap4.rb +12 -0
- data/lib/egov_utils/auth_source.rb +326 -0
- data/lib/egov_utils/engine.rb +84 -0
- data/lib/egov_utils/has_audit_trail.rb +68 -0
- data/lib/egov_utils/user_utils/application_controller_patch.rb +92 -0
- data/lib/egov_utils/user_utils/role.rb +26 -0
- data/lib/egov_utils/version.rb +3 -0
- data/lib/egov_utils.rb +5 -0
- data/lib/grid/shield_grid.rb +9 -0
- data/lib/tasks/egov_utils_tasks.rake +4 -0
- metadata +306 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
begin
|
2
|
+
require_dependency "#{Rails.application.class.parent_name.underscore}/roles"
|
3
|
+
rescue LoadError => e
|
4
|
+
Rails.logger.warning "!! You have not defined roles."
|
5
|
+
Rails.logger.warning "!! Please define it in lib/#{Rails.application.class.parent_name.underscore}/roles."
|
6
|
+
Rails.logger.warning "!! EgovUtils roles management will not work without it."
|
7
|
+
end
|
8
|
+
|
9
|
+
class Ability
|
10
|
+
include CanCan::Ability
|
11
|
+
|
12
|
+
def initialize(user)
|
13
|
+
user.all_roles.each do |role|
|
14
|
+
role.define_abilities(self, user)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module EgovUtils
|
2
|
+
class Address < ApplicationRecord
|
3
|
+
|
4
|
+
# before_safe :identify_address , if: :changed?
|
5
|
+
|
6
|
+
validates :street, :city, length: 3..255
|
7
|
+
validates :postcode, numericality: { only_integer: true }
|
8
|
+
|
9
|
+
District = Struct.new(:id, :name, :region_id)
|
10
|
+
Region = Struct.new(:id, :name)
|
11
|
+
|
12
|
+
def self.districts
|
13
|
+
return @districts if @districts
|
14
|
+
require 'csv'
|
15
|
+
@districts = []
|
16
|
+
CSV.foreach(EgovUtils::Engine.root.join('config', 'okres.csv'), col_sep: ';', headers: true) do |row|
|
17
|
+
@districts << District.new( row[0].to_i, row[1], row[2].to_i) if row[1]
|
18
|
+
end
|
19
|
+
@districts
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.regions
|
23
|
+
return @regions if @regions
|
24
|
+
require 'csv'
|
25
|
+
@regions = []
|
26
|
+
CSV.foreach(EgovUtils::Engine.root.join('config', 'kraj.csv'), col_sep: ';', headers: true) do |row|
|
27
|
+
@regions << Region.new( row[0].to_i, row[1]) if row[1]
|
28
|
+
end
|
29
|
+
@regions
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.region_for_district(district_name)
|
33
|
+
district = districts.detect{|d| d[:name] == district_name }
|
34
|
+
regions.detect{|r| r[:id] == district[:region_id] } if district
|
35
|
+
end
|
36
|
+
|
37
|
+
def district=(value)
|
38
|
+
self.region = self.class.region_for_district(value)[:name]
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
def number
|
43
|
+
if !house_number.blank? && !orientation_number.blank?
|
44
|
+
"#{house_number}/#{orientation_number}"
|
45
|
+
else
|
46
|
+
house_number.presence || orientation_number.presence
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def full_address
|
51
|
+
to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_s
|
55
|
+
"#{street} #{number}, #{postcode} #{city}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def prepare_egon_message(message)
|
59
|
+
message.obec_nazev = city.presence
|
60
|
+
message.cast_obce_nazev = city_part.presence
|
61
|
+
message.ulice_nazev = street.presence
|
62
|
+
message.posta_kod = postcode.presence
|
63
|
+
message.cislo_domovni = house_number.presence
|
64
|
+
message.cislo_orientacni = orientation_number.presence
|
65
|
+
end
|
66
|
+
|
67
|
+
def from_egon_info(message)
|
68
|
+
self.egov_identifier = message[:adresni_misto_kod]
|
69
|
+
self.district = message[:okres_nazev]
|
70
|
+
self.city = message[:obec_nazev]
|
71
|
+
self.city_part = message[:cast_obce_nazev]
|
72
|
+
self.street = message[:ulice_nazev]
|
73
|
+
self.postcode = message[:posta_kod]
|
74
|
+
self.house_number = message[:cislo_domovni]
|
75
|
+
self.orientation_number = message[:cislo_orientacni]+(message[:cislo_orientacni_pismeno] || '')
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module EgovUtils
|
2
|
+
class AuditDetail < ApplicationRecord
|
3
|
+
belongs_to :audit_record
|
4
|
+
|
5
|
+
def value=(arg)
|
6
|
+
write_attribute :value, normalize(arg)
|
7
|
+
end
|
8
|
+
|
9
|
+
def old_value=(arg)
|
10
|
+
write_attribute :old_value, normalize(arg)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def normalize(v)
|
16
|
+
case v
|
17
|
+
when true
|
18
|
+
"1"
|
19
|
+
when false
|
20
|
+
"0"
|
21
|
+
when Date
|
22
|
+
v.strftime("%Y-%m-%d")
|
23
|
+
else
|
24
|
+
v
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module EgovUtils
|
2
|
+
class AuditRecord < ApplicationRecord
|
3
|
+
belongs_to :audited, :polymorphic => true
|
4
|
+
belongs_to :user
|
5
|
+
|
6
|
+
has_many :details, :class_name => "AuditDetail", :dependent => :delete_all, :inverse_of => :audit_record
|
7
|
+
attr_accessor :indice
|
8
|
+
attr_protected :id
|
9
|
+
|
10
|
+
after_create :send_notification
|
11
|
+
|
12
|
+
def save(*args)
|
13
|
+
journalize_changes
|
14
|
+
# Do not save an empty journal
|
15
|
+
(details.empty? && notes.blank?) ? false : super
|
16
|
+
end
|
17
|
+
|
18
|
+
# Stores the values of the attributes and custom fields of the journalized object
|
19
|
+
def start
|
20
|
+
if journalized
|
21
|
+
@attributes_before_change = journalized.journalized_attribute_names.inject({}) do |h, attribute|
|
22
|
+
h[attribute] = journalized.send(attribute)
|
23
|
+
h
|
24
|
+
end
|
25
|
+
end
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
# Adds a journal detail for an attachment that was added or removed
|
30
|
+
def journalize_attachment(attachment, added_or_removed)
|
31
|
+
key = (added_or_removed == :removed ? :old_value : :value)
|
32
|
+
details << JournalDetail.new(
|
33
|
+
:property => 'attachment',
|
34
|
+
:prop_key => attachment.id,
|
35
|
+
key => attachment.filename
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Generates journal details for attribute and custom field changes
|
42
|
+
def journalize_changes
|
43
|
+
# attributes changes
|
44
|
+
if @attributes_before_change
|
45
|
+
journalized.journalized_attribute_names.each {|attribute|
|
46
|
+
before = @attributes_before_change[attribute]
|
47
|
+
after = journalized.send(attribute)
|
48
|
+
next if before == after || (before.blank? && after.blank?)
|
49
|
+
add_attribute_detail(attribute, before, after)
|
50
|
+
}
|
51
|
+
end
|
52
|
+
if @custom_values_before_change
|
53
|
+
# custom fields changes
|
54
|
+
journalized.custom_field_values.each {|c|
|
55
|
+
before = @custom_values_before_change[c.custom_field_id]
|
56
|
+
after = c.value
|
57
|
+
next if before == after || (before.blank? && after.blank?)
|
58
|
+
|
59
|
+
if before.is_a?(Array) || after.is_a?(Array)
|
60
|
+
before = [before] unless before.is_a?(Array)
|
61
|
+
after = [after] unless after.is_a?(Array)
|
62
|
+
|
63
|
+
# values removed
|
64
|
+
(before - after).reject(&:blank?).each do |value|
|
65
|
+
add_custom_value_detail(c, value, nil)
|
66
|
+
end
|
67
|
+
# values added
|
68
|
+
(after - before).reject(&:blank?).each do |value|
|
69
|
+
add_custom_value_detail(c, nil, value)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
add_custom_value_detail(c, before, after)
|
73
|
+
end
|
74
|
+
}
|
75
|
+
end
|
76
|
+
start
|
77
|
+
end
|
78
|
+
|
79
|
+
# Adds a journal detail for an attribute change
|
80
|
+
def add_attribute_detail(attribute, old_value, value)
|
81
|
+
add_detail('attr', attribute, old_value, value)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Adds a journal detail
|
85
|
+
def add_detail(property, prop_key, old_value, value)
|
86
|
+
details << JournalDetail.new(
|
87
|
+
:property => property,
|
88
|
+
:prop_key => prop_key,
|
89
|
+
:old_value => old_value,
|
90
|
+
:value => value
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
def send_notification
|
95
|
+
# TODO
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_dependency 'egov_utils/auth_source'
|
2
|
+
module EgovUtils
|
3
|
+
class Group < Principal
|
4
|
+
validates :name, presence: true, uniqueness: true
|
5
|
+
validates :ldap_uid, uniqueness: true, allow_nil: true
|
6
|
+
|
7
|
+
def members
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
def ldap_members
|
12
|
+
Rails.cache.fetch("#{cache_key}/ldap_members", expires_in: 2.hours) do
|
13
|
+
if provider.present?
|
14
|
+
auth_source.group_members(ldap_uid)
|
15
|
+
else
|
16
|
+
[]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def ldap_member?(user)
|
22
|
+
ldap_members.detect{|mem| mem[:login] == user.login }
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module EgovUtils
|
2
|
+
class Principal < ApplicationRecord
|
3
|
+
self.abstract_class = true
|
4
|
+
|
5
|
+
serialize :roles, Array
|
6
|
+
|
7
|
+
def reload(*attrs)
|
8
|
+
@auth_source = nil
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def has_role?(role)
|
13
|
+
roles.include?(role)
|
14
|
+
end
|
15
|
+
|
16
|
+
def auth_source
|
17
|
+
@auth_source ||= EgovUtils::AuthSource.new(provider) if provider.present?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require_dependency 'egov_utils/auth_source'
|
2
|
+
require 'request_store_rails'
|
3
|
+
|
4
|
+
module EgovUtils
|
5
|
+
class User < Principal
|
6
|
+
has_secure_password validations: false
|
7
|
+
|
8
|
+
serialize :roles, Array
|
9
|
+
|
10
|
+
validates :login, uniqueness: true
|
11
|
+
|
12
|
+
scope :active, -> { where(active: true) }
|
13
|
+
scope :inactive, -> { where(active: false) }
|
14
|
+
|
15
|
+
def self.authenticate(login, password, active_only=true)
|
16
|
+
login = login.to_s
|
17
|
+
password = password.to_s
|
18
|
+
|
19
|
+
# Make sure no one can sign in with an empty login or password
|
20
|
+
return nil if login.empty? || password.empty?
|
21
|
+
user = find_by(login: login) || find_by(mail: login)
|
22
|
+
if user
|
23
|
+
# user is already in local database
|
24
|
+
return nil unless user.password_check?(password)
|
25
|
+
return nil if active_only && !user.active?
|
26
|
+
else
|
27
|
+
# user is not yet registered, try to authenticate with available sources
|
28
|
+
attrs = EgovUtils::AuthSource.authenticate(login, password)
|
29
|
+
if attrs
|
30
|
+
user = new(attrs.merge(active: true))
|
31
|
+
if user.ldap_register_allowed? && user.save
|
32
|
+
user.reload
|
33
|
+
logger.info("User '#{user.login}' created from external auth source: #{user.provider}") if logger && user.auth_source
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
user.update_column(:last_login_at, Time.now) if user && !user.new_record? && user.active?
|
38
|
+
user
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.anonymous
|
42
|
+
self.new
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.current=(user)
|
46
|
+
RequestLocals.store[:current_user] = user || anonymous
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.current
|
50
|
+
RequestLocals.fetch(:current_user) { User.anonymous }
|
51
|
+
end
|
52
|
+
|
53
|
+
def roles
|
54
|
+
logged? ? super : ['anonymous']
|
55
|
+
end
|
56
|
+
|
57
|
+
def ldap_register_allowed?
|
58
|
+
auth_source && auth_source.register_members_only? && ldap_groups.any?
|
59
|
+
end
|
60
|
+
|
61
|
+
def password_check?(password)
|
62
|
+
if provider.present?
|
63
|
+
auth_source.authenticate(login, password)
|
64
|
+
else
|
65
|
+
authenticate(password)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def logged?
|
70
|
+
persisted?
|
71
|
+
end
|
72
|
+
|
73
|
+
def locked?
|
74
|
+
false
|
75
|
+
end
|
76
|
+
|
77
|
+
def fullname
|
78
|
+
"#{firstname} #{lastname}"
|
79
|
+
end
|
80
|
+
|
81
|
+
def admin?
|
82
|
+
has_role?('admin')
|
83
|
+
end
|
84
|
+
|
85
|
+
def has_role?(role_name)
|
86
|
+
all_role_names.include?(role_name)
|
87
|
+
end
|
88
|
+
|
89
|
+
def all_role_names
|
90
|
+
@all_role_names ||= groups.collect{|g| g.roles}.reduce([], :concat) + roles
|
91
|
+
end
|
92
|
+
|
93
|
+
def all_roles
|
94
|
+
all_role_names.map{|rn| EgovUtils::UserUtils::Role.find(rn) }.compact.collect{|cls| cls.new }
|
95
|
+
end
|
96
|
+
|
97
|
+
def groups
|
98
|
+
ldap_groups || []
|
99
|
+
end
|
100
|
+
|
101
|
+
def ldap_groups
|
102
|
+
if provider.present?
|
103
|
+
EgovUtils::Group.where(provider: provider).to_a.select{|g| g.ldap_member?(self) }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module EgovUtils
|
2
|
+
class AddressSchema < AzaharaSchema::ModelSchema
|
3
|
+
|
4
|
+
def attribute_for_column(col)
|
5
|
+
case col.name
|
6
|
+
when 'district'
|
7
|
+
EgovUtils::District.new
|
8
|
+
when 'region'
|
9
|
+
EgovUtils::Region.new
|
10
|
+
else
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def main_attribute_name
|
16
|
+
'full_address'
|
17
|
+
end
|
18
|
+
|
19
|
+
def path
|
20
|
+
'to_s'
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize_available_attributes
|
24
|
+
@available_attributes ||= []
|
25
|
+
@available_attributes << FullAddress.new
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class EmailValidator < ActiveModel::EachValidator
|
2
|
+
def validate_each(record, attribute, value)
|
3
|
+
return if options[:allow_nil] && value.presence.nil?
|
4
|
+
unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
|
5
|
+
record.errors.add(attribute, (options[:message] || :email_format))
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
$ ->
|
2
|
+
<%
|
3
|
+
grid ||= schema.outputs.grid
|
4
|
+
additional_params ||= {}
|
5
|
+
%>
|
6
|
+
|
7
|
+
$('body').off 'egov:submitted'
|
8
|
+
$('body').on 'egov:submitted', '#modal', (evt, data)->
|
9
|
+
grid = $("#<%= grid_id %>").swidget()
|
10
|
+
grid.dataSource.read()
|
11
|
+
|
12
|
+
<%# would be a bit cleaner to give the filled form to the shield grid create method, then send the form by ajax %>
|
13
|
+
createRecord = (evt)->
|
14
|
+
$.ajax('<%= new_polymorphic_path(schema.model, format: :js) %>')
|
15
|
+
|
16
|
+
|
17
|
+
editRecord = (index)->
|
18
|
+
grid = $("#<%= grid_id %>").swidget()
|
19
|
+
item = grid.dataItem(index)
|
20
|
+
$.ajax('<%= polymorphic_path(schema.model) %>/'+item.id+'/edit.js')
|
21
|
+
|
22
|
+
<% if local_assigns[:detail_for] %>
|
23
|
+
<% detail_col = schema.column(detail_for) %>
|
24
|
+
detailCreated = (evt)->
|
25
|
+
$("<div/>").appendTo(evt.detailCell).shieldGrid
|
26
|
+
dataSource:
|
27
|
+
remote:
|
28
|
+
read:
|
29
|
+
type: 'GET'
|
30
|
+
url: '<%= polymorphic_path(schema.model) %>/'+evt.item.id+'<%= polymorphic_path(detail_for, format: :json) %>'
|
31
|
+
dataType: 'json'
|
32
|
+
paging:
|
33
|
+
pageSize: 5
|
34
|
+
columns: [
|
35
|
+
<% detail_col.schema.columns.each do |col| %>
|
36
|
+
<%= raw column_for_grid(detail_col.schema.outputs.grid, col) %>
|
37
|
+
<% end %>
|
38
|
+
]
|
39
|
+
<% end %>
|
40
|
+
|
41
|
+
$('#<%= grid_id %>').shieldGrid({
|
42
|
+
noRecordsText: '<%= t('label_no_records') %>'
|
43
|
+
dataSource: {
|
44
|
+
schema:
|
45
|
+
fields:
|
46
|
+
<% schema.available_columns.each do |column| %>
|
47
|
+
<%= raw field_for_grid(column) %>
|
48
|
+
<% end %>
|
49
|
+
events:
|
50
|
+
error: (event) ->
|
51
|
+
if event.errorType == 'transport'
|
52
|
+
alert("Write error: " + event.error.statusText )
|
53
|
+
if event.operation == 'save'
|
54
|
+
this.read()
|
55
|
+
else
|
56
|
+
alert( event.errorType + " error: " + event.error )
|
57
|
+
remote: {
|
58
|
+
read: {
|
59
|
+
type: 'GET'
|
60
|
+
url: '<%= polymorphic_path(schema.model, schema.to_param.merge(additional_params).merge(format: :json)) %>'
|
61
|
+
dataType: 'json'
|
62
|
+
}
|
63
|
+
modify: {
|
64
|
+
create: (items, success, error) ->
|
65
|
+
newItem = items[0]
|
66
|
+
$.ajax
|
67
|
+
url: '<%= polymorphic_path(schema.model, format: :json) %>'
|
68
|
+
type: 'POST'
|
69
|
+
dataType: 'json'
|
70
|
+
data: { <%= grid.model_name.name.underscore %>: newItem.data }
|
71
|
+
complete: (xhr) ->
|
72
|
+
if xhr.readyState == 4 and xhr.status == 201
|
73
|
+
newItem.data.id = xhr.responseJSON.id
|
74
|
+
success()
|
75
|
+
return
|
76
|
+
error(xhr)
|
77
|
+
# remove: (items, success, error) ->
|
78
|
+
# $.ajax(
|
79
|
+
# type: "DELETE"
|
80
|
+
# url: "<%= polymorphic_path(schema.model) %>/" + items[0].data.id + '.json'
|
81
|
+
# dataType: 'json'
|
82
|
+
# ).then(success, error)
|
83
|
+
}
|
84
|
+
operations: ['sort']
|
85
|
+
}
|
86
|
+
},
|
87
|
+
columns: [
|
88
|
+
<% schema.columns.each do |col| %>
|
89
|
+
<%= raw column_for_grid(grid, col) %>
|
90
|
+
<% end %>
|
91
|
+
<% if can?(:update, schema.model) || can?(:destroy, schema.model) %>
|
92
|
+
{
|
93
|
+
width: 150
|
94
|
+
title: " "
|
95
|
+
buttons: [
|
96
|
+
<% if can?(:update, schema.model) %>
|
97
|
+
{cls: 'btn btn-sm btn-primary', caption: '<%= t('label_edit') %>', click: editRecord}
|
98
|
+
<% end %>
|
99
|
+
# <% if can?(:destroy, schema.model) %>
|
100
|
+
# {commandName: 'delete', caption: '<%= t('label_delete') %>'}
|
101
|
+
# <% end %>
|
102
|
+
]
|
103
|
+
}
|
104
|
+
<% end %>
|
105
|
+
],
|
106
|
+
sorting:
|
107
|
+
multiple: false
|
108
|
+
editing:
|
109
|
+
enabled: <%= can?(:update, schema.model) || can?(:destroy, schema.model) %>
|
110
|
+
type: 'row'
|
111
|
+
<% if local_assigns[:detail_for] %>
|
112
|
+
events:
|
113
|
+
detailCreated: detailCreated
|
114
|
+
<% end %>
|
115
|
+
<% if can? :create, schema.model %>
|
116
|
+
toolbar: [
|
117
|
+
{
|
118
|
+
buttons: [
|
119
|
+
{ cls: 'btn btn-primary', caption: '<%= t('helpers.submit.create', model: grid.model_name.human) %>', click: createRecord }
|
120
|
+
],
|
121
|
+
position: 'top'
|
122
|
+
}
|
123
|
+
]
|
124
|
+
<% end %>
|
125
|
+
});
|
126
|
+
|
127
|
+
destroy_evt_method = (evt)->
|
128
|
+
$('#<%= grid_id %>').shieldGrid('destroy')
|
129
|
+
$(document).off 'turbolinks:before-cache', destroy_evt_method
|
130
|
+
$(document).on 'turbolinks:before-cache', destroy_evt_method
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#modal.modal.fade
|
2
|
+
.modal-dialog{ role: "document" }
|
3
|
+
.modal-content
|
4
|
+
.modal-header
|
5
|
+
%h5.modal-title Modal
|
6
|
+
%button.close{ 'type' => "button", 'data-dismiss'=>"modal", 'aria-label'=>"Close" }
|
7
|
+
%span{'aria-hidden'=> true } ×
|
8
|
+
.modal-body
|
9
|
+
.modal-footer
|
10
|
+
/<button type="button" class="btn btn-primary">Save changes</button>
|
11
|
+
/<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
@@ -0,0 +1,51 @@
|
|
1
|
+
.row.address-fields
|
2
|
+
= form.hidden_field :egov_identifier
|
3
|
+
.col-6
|
4
|
+
= form.text_field :street
|
5
|
+
.col-3
|
6
|
+
= form.text_field :house_number
|
7
|
+
.col-3
|
8
|
+
= form.text_field :orientation_number
|
9
|
+
.col-12
|
10
|
+
= form.text_field :city
|
11
|
+
= form.text_field :postcode
|
12
|
+
= form.text_field :district
|
13
|
+
= form.select :region, EgovUtils::Address.regions.collect{|r| [r[:name],r[:name]]}
|
14
|
+
-# form.text_field :country
|
15
|
+
%div.validation-button
|
16
|
+
= link_to t('label_find'), 'javascript:void(0)', class: 'btn btn-secondary address-validator-btn'
|
17
|
+
|
18
|
+
:javascript
|
19
|
+
$(function(){
|
20
|
+
$('.address-validator-btn').not('.validator-initialized').on('click', function(evt) {
|
21
|
+
var values = {},
|
22
|
+
$fields = $(this).closest('.address-fields');
|
23
|
+
|
24
|
+
$fields.find(':input').each(function(i){
|
25
|
+
var name,
|
26
|
+
name_m = $(this).attr('name').match(/\[([^\[]*)\]$/);
|
27
|
+
name = name_m[1];
|
28
|
+
values[name] = $(this).val();
|
29
|
+
});
|
30
|
+
$.ajax('#{egov_utils.validate_ruian_path}', {
|
31
|
+
method: 'GET',
|
32
|
+
dataType: 'json',
|
33
|
+
data: {
|
34
|
+
address: values
|
35
|
+
}
|
36
|
+
}).done(function(json){
|
37
|
+
var field;
|
38
|
+
for( var key in json ) {
|
39
|
+
field = $fields.find("[name$='["+key+"]']");
|
40
|
+
if( field.length !== 1 || !json[key] )
|
41
|
+
continue;
|
42
|
+
field.val(json[key]);
|
43
|
+
}
|
44
|
+
}).fail(function(xhr, status, errorMsg){
|
45
|
+
$('#modal').modal('hide');
|
46
|
+
eGovUtilities.showModal(xhr.responseJSON.error, {modalId: 'modalAlert', backdrop: 'static'}).on('hidden.bs.modal', function(){
|
47
|
+
$('#modal').modal('show');
|
48
|
+
});
|
49
|
+
});
|
50
|
+
}).addClass('.validator-initialized');
|
51
|
+
});
|
@@ -0,0 +1,29 @@
|
|
1
|
+
%h3= EgovUtils::User.model_name.human(count: :other)
|
2
|
+
%table#user_roles.table
|
3
|
+
%thead
|
4
|
+
%tr
|
5
|
+
%th= EgovUtils::User.human_attribute_name('fullname')
|
6
|
+
%th= EgovUtils::User.human_attribute_name('roles')
|
7
|
+
%tbody
|
8
|
+
- @users.each do |user|
|
9
|
+
%tr
|
10
|
+
%td= user.fullname
|
11
|
+
%td.roles{data: {roles: user.roles, id: user.id}}= user.roles.join(', ')
|
12
|
+
|
13
|
+
%h3= EgovUtils::Group.model_name.human(count: :other)
|
14
|
+
%table#group_roles.table
|
15
|
+
%thead
|
16
|
+
%tr
|
17
|
+
%th= EgovUtils::Group.human_attribute_name('name')
|
18
|
+
%th= EgovUtils::Group.human_attribute_name('roles')
|
19
|
+
%tbody
|
20
|
+
- @groups.each do |group|
|
21
|
+
%tr
|
22
|
+
%td= group.name
|
23
|
+
%td.roles{data: {roles: group.roles, id: group.id}}= group.roles.join(', ')
|
24
|
+
|
25
|
+
:javascript
|
26
|
+
$(function(){
|
27
|
+
$('#user_roles tbody').roles({ url: '#{roles_path(entity_class: 'EgovUtils::User')}' });
|
28
|
+
$('#group_roles tbody').roles({ url: '#{roles_path(entity_class: 'EgovUtils::Group')}' });
|
29
|
+
});
|