egov_utils 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +26 -0
  5. data/app/assets/config/egov_utils_manifest.js +2 -0
  6. data/app/assets/javascripts/egov_utils/application.js +23 -0
  7. data/app/assets/javascripts/egov_utils/eGovUtilities.coffee.erb +70 -0
  8. data/app/assets/javascripts/egov_utils/groups.js +2 -0
  9. data/app/assets/javascripts/egov_utils/roles.coffee.erb +56 -0
  10. data/app/assets/javascripts/egov_utils/setup_locale.coffee.erb +2 -0
  11. data/app/assets/javascripts/egov_utils/users.js +2 -0
  12. data/app/assets/stylesheets/egov_utils/application.scss +15 -0
  13. data/app/assets/stylesheets/egov_utils/groups.css +4 -0
  14. data/app/assets/stylesheets/egov_utils/roles.css +4 -0
  15. data/app/assets/stylesheets/egov_utils/users.css +4 -0
  16. data/app/attributes/egov_utils/district.rb +13 -0
  17. data/app/attributes/egov_utils/full_address.rb +17 -0
  18. data/app/attributes/egov_utils/region.rb +13 -0
  19. data/app/controllers/egov_utils/addresses_controller.rb +34 -0
  20. data/app/controllers/egov_utils/application_controller.rb +7 -0
  21. data/app/controllers/egov_utils/groups_controller.rb +27 -0
  22. data/app/controllers/egov_utils/roles_controller.rb +28 -0
  23. data/app/controllers/egov_utils/sessions_controller.rb +83 -0
  24. data/app/controllers/egov_utils/users_controller.rb +64 -0
  25. data/app/helpers/egov_utils/application_helper.rb +4 -0
  26. data/app/helpers/egov_utils/grid_helper.rb +40 -0
  27. data/app/helpers/egov_utils/groups_helper.rb +4 -0
  28. data/app/helpers/egov_utils/roles_helper.rb +4 -0
  29. data/app/helpers/egov_utils/users_helper.rb +4 -0
  30. data/app/jobs/egov_utils/application_job.rb +4 -0
  31. data/app/mailers/egov_utils/application_mailer.rb +6 -0
  32. data/app/models/ability.rb +17 -0
  33. data/app/models/egov_utils/address.rb +79 -0
  34. data/app/models/egov_utils/application_record.rb +5 -0
  35. data/app/models/egov_utils/audit_detail.rb_bac +28 -0
  36. data/app/models/egov_utils/audit_record.rb_bac +98 -0
  37. data/app/models/egov_utils/group.rb +26 -0
  38. data/app/models/egov_utils/person.rb +9 -0
  39. data/app/models/egov_utils/principal.rb +20 -0
  40. data/app/models/egov_utils/user.rb +108 -0
  41. data/app/schemas/egov_utils/address_schema.rb +30 -0
  42. data/app/validators/email_validator.rb +8 -0
  43. data/app/validators/ico_validator.rb +7 -0
  44. data/app/views/common/_grid.html.coffee +130 -0
  45. data/app/views/common/_modal.html.haml +11 -0
  46. data/app/views/egov_utils/addresses/_form.html.haml +51 -0
  47. data/app/views/egov_utils/people/_form.html.haml +3 -0
  48. data/app/views/egov_utils/roles/index.html.haml +29 -0
  49. data/app/views/egov_utils/sessions/new.html.haml +5 -0
  50. data/app/views/egov_utils/users/_form.html.haml +6 -0
  51. data/app/views/egov_utils/users/index.html.haml +62 -0
  52. data/app/views/egov_utils/users/new.html.haml +3 -0
  53. data/app/views/egov_utils/users/show.html.haml +1 -0
  54. data/app/views/errors/error_403.html.haml +1 -0
  55. data/app/views/layouts/egov_utils/_messages.html.haml +7 -0
  56. data/app/views/layouts/egov_utils/application.html.erb +14 -0
  57. data/config/kraj.csv +16 -0
  58. data/config/locales/cs.yml +80 -0
  59. data/config/okres.csv +79 -0
  60. data/config/routes.rb +21 -0
  61. data/db/migrate/20170313100505_create_egov_utils_addresses.rb +18 -0
  62. data/db/migrate/20170315134217_create_egov_utils_users.rb +16 -0
  63. data/db/migrate/20170513115712_create_egov_utils_audit_records.rb_bac +11 -0
  64. data/db/migrate/20170513120006_create_egov_utils_audit_details.rb_bac +13 -0
  65. data/db/migrate/20170630150633_add_provider_to_user.rb +5 -0
  66. data/db/migrate/20170801154511_install_audited.rb +30 -0
  67. data/db/migrate/20170809150646_create_egov_utils_people.rb +12 -0
  68. data/db/migrate/20170824111701_create_egov_utils_groups.rb +12 -0
  69. data/lib/bootstrap_form/datetimepicker.rb +17 -0
  70. data/lib/bootstrap_form/helpers/bootstrap4.rb +12 -0
  71. data/lib/egov_utils/auth_source.rb +326 -0
  72. data/lib/egov_utils/engine.rb +84 -0
  73. data/lib/egov_utils/has_audit_trail.rb +68 -0
  74. data/lib/egov_utils/user_utils/application_controller_patch.rb +92 -0
  75. data/lib/egov_utils/user_utils/role.rb +26 -0
  76. data/lib/egov_utils/version.rb +3 -0
  77. data/lib/egov_utils.rb +5 -0
  78. data/lib/grid/shield_grid.rb +9 -0
  79. data/lib/tasks/egov_utils_tasks.rake +4 -0
  80. 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,5 @@
1
+ module EgovUtils
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ 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,9 @@
1
+ module EgovUtils
2
+ class Person < ApplicationRecord
3
+
4
+ def fullname
5
+ firstname.to_s + ' ' + lastname.to_s
6
+ end
7
+
8
+ end
9
+ 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,7 @@
1
+ class IcoValidator < ActiveModel::EachValidator
2
+ def validate_each(record, attribute, value)
3
+ unless !value.nil? && value =~ /\A\d{7,9}\z/
4
+ record.errors.add(attribute, (options[:message] || :ico_format))
5
+ end
6
+ end
7
+ 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 } &times;
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,3 @@
1
+ = form.text_field(:firstname)
2
+ = form.text_field(:lastname)
3
+ = form.date_field(:birth_date)
@@ -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
+ });
@@ -0,0 +1,5 @@
1
+ = bootstrap_form_for(:session) do |f|
2
+ = f.text_field(:username)
3
+ = f.password_field(:password)
4
+ = f.submit
5
+ -# link_to t('label_register'), new_user_path
@@ -0,0 +1,6 @@
1
+ = form.text_field :login
2
+ = form.text_field :mail
3
+ = form.password_field :password
4
+ = form.password_field :password_confirmation
5
+ = form.text_field :firstname
6
+ = form.text_field :lastname