introspective_admin 0.1.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.travis.yml +5 -14
- data/CHANGELOG.md +37 -28
- data/Gemfile +15 -6
- data/Gemfile.lock +347 -264
- data/README.md +34 -8
- data/introspective_admin.gemspec +34 -44
- data/lib/introspective_admin/base.rb +200 -200
- data/lib/introspective_admin/version.rb +3 -3
- data/spec/admin/company_admin_spec.rb +72 -72
- data/spec/admin/job_admin_spec.rb +61 -61
- data/spec/admin/location_admin_spec.rb +66 -66
- data/spec/admin/location_beacon_admin_spec.rb +73 -73
- data/spec/admin/project__admin_spec.rb +71 -71
- data/spec/admin/user_admin_spec.rb +64 -64
- data/spec/dummy/Gemfile +15 -0
- data/spec/dummy/README.rdoc +28 -28
- data/spec/dummy/Rakefile +6 -6
- data/spec/dummy/app/admin/admin_users.rb +28 -0
- data/spec/dummy/app/admin/company_admin.rb +4 -4
- data/spec/dummy/app/admin/dashboard.rb +32 -0
- data/spec/dummy/app/admin/job_admin.rb +4 -4
- data/spec/dummy/app/admin/location_admin.rb +4 -4
- data/spec/dummy/app/admin/location_beacon_admin.rb +6 -6
- data/spec/dummy/app/admin/project_admin.rb +6 -6
- data/spec/dummy/app/admin/role_admin.rb +5 -5
- data/spec/dummy/app/admin/user_admin.rb +13 -13
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/javascripts/active_admin.js +1 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -13
- data/spec/dummy/app/assets/stylesheets/active_admin.scss +17 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -15
- data/spec/dummy/app/controllers/application_controller.rb +8 -8
- data/spec/dummy/app/helpers/application_helper.rb +3 -3
- data/spec/dummy/app/models/abstract_adapter.rb +18 -12
- data/spec/dummy/app/models/admin_user.rb +10 -6
- data/spec/dummy/app/models/company.rb +12 -12
- data/spec/dummy/app/models/job.rb +10 -10
- data/spec/dummy/app/models/locatable.rb +6 -6
- data/spec/dummy/app/models/location.rb +26 -26
- data/spec/dummy/app/models/location_beacon.rb +19 -19
- data/spec/dummy/app/models/location_gps.rb +11 -11
- data/spec/dummy/app/models/project.rb +20 -20
- data/spec/dummy/app/models/project_job.rb +7 -7
- data/spec/dummy/app/models/role.rb +25 -25
- data/spec/dummy/app/models/team.rb +9 -9
- data/spec/dummy/app/models/team_user.rb +13 -13
- data/spec/dummy/app/models/user.rb +68 -68
- data/spec/dummy/app/models/user_location.rb +28 -28
- data/spec/dummy/app/models/user_project_job.rb +16 -16
- data/spec/dummy/app/views/layouts/application.html.erb +13 -13
- data/spec/dummy/bin/bundle +3 -3
- data/spec/dummy/bin/rails +4 -4
- data/spec/dummy/bin/rake +4 -4
- data/spec/dummy/bin/setup +29 -29
- data/spec/dummy/config/application.rb +34 -34
- data/spec/dummy/config/boot.rb +5 -5
- data/spec/dummy/config/database.yml +22 -22
- data/spec/dummy/config/environment.rb +11 -11
- data/spec/dummy/config/environments/development.rb +45 -45
- data/spec/dummy/config/environments/production.rb +82 -82
- data/spec/dummy/config/environments/test.rb +50 -50
- data/spec/dummy/config/initializers/active_admin.rb +7 -7
- data/spec/dummy/config/initializers/assets.rb +13 -13
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -7
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -3
- data/spec/dummy/config/initializers/devise.rb +263 -263
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -4
- data/spec/dummy/config/initializers/inflections.rb +16 -16
- data/spec/dummy/config/initializers/mime_types.rb +4 -4
- data/spec/dummy/config/initializers/session_store.rb +3 -3
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -14
- data/spec/dummy/config/initializers/zeitwerk.rb +8 -0
- data/spec/dummy/config/locales/devise.en.yml +60 -60
- data/spec/dummy/config/locales/en.yml +23 -23
- data/spec/dummy/config/routes.rb +10 -9
- data/spec/dummy/config/secrets.yml +20 -20
- data/spec/dummy/config.ru +4 -4
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/development.sqlite3-shm +0 -0
- data/spec/dummy/db/development.sqlite3-wal +0 -0
- data/spec/dummy/db/migrate/20141002205024_devise_create_users.rb +42 -42
- data/spec/dummy/db/migrate/20141002211055_devise_create_admin_users.rb +48 -48
- data/spec/dummy/db/migrate/20141002211057_create_active_admin_comments.rb +19 -19
- data/spec/dummy/db/migrate/20141002220722_add_lockable_to_users.rb +8 -8
- data/spec/dummy/db/migrate/20150406213646_create_companies.rb +11 -11
- data/spec/dummy/db/migrate/20150414213154_add_user_authentication_token.rb +11 -11
- data/spec/dummy/db/migrate/20150415222005_create_roles.rb +12 -12
- data/spec/dummy/db/migrate/20150505181635_create_chats.rb +9 -9
- data/spec/dummy/db/migrate/20150505181636_create_chat_users.rb +11 -11
- data/spec/dummy/db/migrate/20150505181640_create_chat_messages.rb +11 -11
- data/spec/dummy/db/migrate/20150507191529_create_chat_message_users.rb +11 -11
- data/spec/dummy/db/migrate/20150601200526_create_locations.rb +13 -13
- data/spec/dummy/db/migrate/20150601200533_create_locatables.rb +10 -10
- data/spec/dummy/db/migrate/20150601212924_create_location_beacons.rb +16 -16
- data/spec/dummy/db/migrate/20150601213542_create_location_gps.rb +12 -12
- data/spec/dummy/db/migrate/20150609201823_create_user_locations.rb +14 -14
- data/spec/dummy/db/migrate/20150617232519_create_projects.rb +10 -10
- data/spec/dummy/db/migrate/20150617232521_create_jobs.rb +9 -9
- data/spec/dummy/db/migrate/20150617232522_create_project_jobs.rb +11 -11
- data/spec/dummy/db/migrate/20150623170133_create_user_project_jobs.rb +12 -12
- data/spec/dummy/db/migrate/20150701234929_create_teams.rb +11 -11
- data/spec/dummy/db/migrate/20150701234930_create_team_users.rb +11 -11
- data/spec/dummy/db/migrate/20150727214950_add_confirmable_to_devise.rb +11 -11
- data/spec/dummy/db/migrate/20150820190524_add_user_names.rb +6 -6
- data/spec/dummy/db/migrate/20150909225019_add_password_to_project.rb +5 -5
- data/spec/dummy/db/migrate/20220806003731_add_devise_to_admin_users.rb +51 -0
- data/spec/dummy/db/schema.rb +264 -264
- data/spec/dummy/introspective_admin.gemspec +34 -0
- data/spec/dummy/public/404.html +67 -67
- data/spec/dummy/public/422.html +67 -67
- data/spec/dummy/public/500.html +66 -66
- data/spec/rails_helper.rb +27 -27
- metadata +25 -116
- data/Gemfile.lock.rails4 +0 -256
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
class AdminUser < ActiveRecord::Base
|
|
2
|
-
# Include default devise modules. Others available are:
|
|
3
|
-
# :confirmable, :lockable, :timeoutable and :omniauthable
|
|
4
|
-
devise :database_authenticatable,
|
|
5
|
-
:recoverable, :rememberable, :
|
|
6
|
-
|
|
1
|
+
class AdminUser < ActiveRecord::Base
|
|
2
|
+
# Include default devise modules. Others available are:
|
|
3
|
+
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
|
4
|
+
devise :database_authenticatable,
|
|
5
|
+
:recoverable, :rememberable, :validatable
|
|
6
|
+
# Include default devise modules. Others available are:
|
|
7
|
+
# :confirmable, :lockable, :timeoutable and :omniauthable
|
|
8
|
+
devise :database_authenticatable,
|
|
9
|
+
:recoverable, :rememberable, :trackable, :validatable
|
|
10
|
+
end
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
class Company < AbstractAdapter
|
|
2
|
-
has_many :roles, as: :ownable
|
|
3
|
-
has_many :admins, through: :roles, source: :user
|
|
4
|
-
accepts_nested_attributes_for :roles, allow_destroy: true
|
|
5
|
-
|
|
6
|
-
has_many :beacons, class_name: 'LocationBeacon', dependent: :destroy
|
|
7
|
-
has_many :locatables
|
|
8
|
-
has_many :locations, through: :locatables, source: :locatable, source_type: 'Company'
|
|
9
|
-
|
|
10
|
-
has_many :projects, foreign_key: :owner_id, dependent: :destroy, inverse_of: :owner
|
|
11
|
-
|
|
12
|
-
end
|
|
1
|
+
class Company < AbstractAdapter
|
|
2
|
+
has_many :roles, as: :ownable
|
|
3
|
+
has_many :admins, through: :roles, source: :user
|
|
4
|
+
accepts_nested_attributes_for :roles, allow_destroy: true
|
|
5
|
+
|
|
6
|
+
has_many :beacons, class_name: 'LocationBeacon', dependent: :destroy
|
|
7
|
+
has_many :locatables
|
|
8
|
+
has_many :locations, through: :locatables, source: :locatable, source_type: 'Company'
|
|
9
|
+
|
|
10
|
+
has_many :projects, foreign_key: :owner_id, dependent: :destroy, inverse_of: :owner
|
|
11
|
+
|
|
12
|
+
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
class Job < AbstractAdapter
|
|
2
|
-
|
|
3
|
-
has_many :project_jobs, dependent: :destroy
|
|
4
|
-
accepts_nested_attributes_for :project_jobs, allow_destroy: true
|
|
5
|
-
|
|
6
|
-
has_many :user_project_jobs, dependent: :destroy
|
|
7
|
-
has_many :users, through: :user_project_jobs
|
|
8
|
-
has_many :projects, through: :user_project_jobs
|
|
9
|
-
|
|
10
|
-
end
|
|
1
|
+
class Job < AbstractAdapter
|
|
2
|
+
|
|
3
|
+
has_many :project_jobs, dependent: :destroy
|
|
4
|
+
accepts_nested_attributes_for :project_jobs, allow_destroy: true
|
|
5
|
+
|
|
6
|
+
has_many :user_project_jobs, dependent: :destroy
|
|
7
|
+
has_many :users, through: :user_project_jobs
|
|
8
|
+
has_many :projects, through: :user_project_jobs
|
|
9
|
+
|
|
10
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
class Locatable < AbstractAdapter
|
|
2
|
-
belongs_to :location
|
|
3
|
-
belongs_to :locatable, polymorphic: true
|
|
4
|
-
|
|
5
|
-
validates_inclusion_of :locatable_type, in: %w(Company)
|
|
6
|
-
end
|
|
1
|
+
class Locatable < AbstractAdapter
|
|
2
|
+
belongs_to :location
|
|
3
|
+
belongs_to :locatable, polymorphic: true
|
|
4
|
+
|
|
5
|
+
validates_inclusion_of :locatable_type, in: %w(Company)
|
|
6
|
+
end
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
class Location < AbstractAdapter
|
|
2
|
-
has_many :locatables, dependent: :destroy
|
|
3
|
-
has_many :companies, through: :locatables, source: :locatable, source_type: 'Company'
|
|
4
|
-
|
|
5
|
-
has_many :beacons, class_name: 'LocationBeacon', dependent: :destroy
|
|
6
|
-
has_one :gps, class_name: 'LocationGps', dependent: :destroy
|
|
7
|
-
delegate :lat,:lng,:alt, to: :gps
|
|
8
|
-
|
|
9
|
-
belongs_to :parent_location, foreign_key: :parent_location_id, class_name: 'Location', inverse_of: :child_locations
|
|
10
|
-
has_many :child_locations, foreign_key: :parent_location_id, class_name: 'Location', dependent: :destroy, inverse_of: :parent_location
|
|
11
|
-
|
|
12
|
-
has_many :user_locations, dependent: :destroy
|
|
13
|
-
|
|
14
|
-
# isn't this list going to be kinda long? are there any reasonable constraints to put
|
|
15
|
-
# on this random bit of metadata?
|
|
16
|
-
validates_inclusion_of :kind, in: %w(airport terminal gate plane)
|
|
17
|
-
|
|
18
|
-
accepts_nested_attributes_for :child_locations, allow_destroy: true
|
|
19
|
-
accepts_nested_attributes_for :gps, allow_destroy: true
|
|
20
|
-
accepts_nested_attributes_for :beacons, allow_destroy: true
|
|
21
|
-
|
|
22
|
-
def coords
|
|
23
|
-
[gps.lat, gps.lng, gps.alt]
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
end
|
|
1
|
+
class Location < AbstractAdapter
|
|
2
|
+
has_many :locatables, dependent: :destroy
|
|
3
|
+
has_many :companies, through: :locatables, source: :locatable, source_type: 'Company'
|
|
4
|
+
|
|
5
|
+
has_many :beacons, class_name: 'LocationBeacon', dependent: :destroy
|
|
6
|
+
has_one :gps, class_name: 'LocationGps', dependent: :destroy
|
|
7
|
+
delegate :lat,:lng,:alt, to: :gps
|
|
8
|
+
|
|
9
|
+
belongs_to :parent_location, foreign_key: :parent_location_id, class_name: 'Location', inverse_of: :child_locations
|
|
10
|
+
has_many :child_locations, foreign_key: :parent_location_id, class_name: 'Location', dependent: :destroy, inverse_of: :parent_location
|
|
11
|
+
|
|
12
|
+
has_many :user_locations, dependent: :destroy
|
|
13
|
+
|
|
14
|
+
# isn't this list going to be kinda long? are there any reasonable constraints to put
|
|
15
|
+
# on this random bit of metadata?
|
|
16
|
+
validates_inclusion_of :kind, in: %w(airport terminal gate plane)
|
|
17
|
+
|
|
18
|
+
accepts_nested_attributes_for :child_locations, allow_destroy: true
|
|
19
|
+
accepts_nested_attributes_for :gps, allow_destroy: true
|
|
20
|
+
accepts_nested_attributes_for :beacons, allow_destroy: true
|
|
21
|
+
|
|
22
|
+
def coords
|
|
23
|
+
[gps.lat, gps.lng, gps.alt]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
class LocationBeacon < AbstractAdapter
|
|
2
|
-
belongs_to :location
|
|
3
|
-
has_many :gps, through: :location
|
|
4
|
-
belongs_to :company
|
|
5
|
-
|
|
6
|
-
# B9407F30-F5F8-466E-AFF9-25556B57FE6D
|
|
7
|
-
validates_format_of :uuid, with: /[0-9a-fA-F]{32}/ # 32 digit hexadecimal UUID
|
|
8
|
-
validates_format_of :mac_address, with: /[0-9a-fA-F]{12}/ # 16 digit hexadecimal bluetooth MAC address
|
|
9
|
-
|
|
10
|
-
before_validation :massage_ids
|
|
11
|
-
def massage_ids
|
|
12
|
-
self.uuid = (uuid||'').gsub(/[^0-9a-fA-F]+/,'').upcase
|
|
13
|
-
self.mac_address = (mac_address||'').gsub(/[^0-9a-fA-F]+/,'').upcase
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
scope :low_battery, -> { where("last_known_battery_level < 20") }
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
end
|
|
1
|
+
class LocationBeacon < AbstractAdapter
|
|
2
|
+
belongs_to :location
|
|
3
|
+
has_many :gps, through: :location
|
|
4
|
+
belongs_to :company
|
|
5
|
+
|
|
6
|
+
# B9407F30-F5F8-466E-AFF9-25556B57FE6D
|
|
7
|
+
validates_format_of :uuid, with: /[0-9a-fA-F]{32}/ # 32 digit hexadecimal UUID
|
|
8
|
+
validates_format_of :mac_address, with: /[0-9a-fA-F]{12}/ # 16 digit hexadecimal bluetooth MAC address
|
|
9
|
+
|
|
10
|
+
before_validation :massage_ids
|
|
11
|
+
def massage_ids
|
|
12
|
+
self.uuid = (uuid||'').gsub(/[^0-9a-fA-F]+/,'').upcase
|
|
13
|
+
self.mac_address = (mac_address||'').gsub(/[^0-9a-fA-F]+/,'').upcase
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
scope :low_battery, -> { where("last_known_battery_level < 20") }
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
class LocationGps < AbstractAdapter
|
|
2
|
-
belongs_to :location
|
|
3
|
-
has_many :beacons, through: :location
|
|
4
|
-
|
|
5
|
-
# lat and lng in degrees altitude in meters
|
|
6
|
-
validates_numericality_of :lat, greater_than_or_equal_to: -90.0, less_than_or_equal_to: 90.0
|
|
7
|
-
validates_numericality_of :lng, greater_than_or_equal_to: -180.0, less_than_or_equal_to: 180.0
|
|
8
|
-
validates_numericality_of :alt
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
end
|
|
1
|
+
class LocationGps < AbstractAdapter
|
|
2
|
+
belongs_to :location
|
|
3
|
+
has_many :beacons, through: :location
|
|
4
|
+
|
|
5
|
+
# lat and lng in degrees altitude in meters
|
|
6
|
+
validates_numericality_of :lat, greater_than_or_equal_to: -90.0, less_than_or_equal_to: 90.0
|
|
7
|
+
validates_numericality_of :lng, greater_than_or_equal_to: -180.0, less_than_or_equal_to: 180.0
|
|
8
|
+
validates_numericality_of :alt
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
end
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
class Project < AbstractAdapter
|
|
2
|
-
belongs_to :owner, foreign_key: :owner_id, class_name: 'Company'
|
|
3
|
-
|
|
4
|
-
has_many :roles, as: :ownable
|
|
5
|
-
has_many :admins, through: :roles, source: :user
|
|
6
|
-
accepts_nested_attributes_for :roles, allow_destroy: true
|
|
7
|
-
|
|
8
|
-
has_many :project_jobs, dependent: :destroy, inverse_of: :project
|
|
9
|
-
has_many :jobs, through: :project_jobs
|
|
10
|
-
accepts_nested_attributes_for :project_jobs, allow_destroy: true
|
|
11
|
-
|
|
12
|
-
has_many :user_project_jobs, dependent: :destroy, inverse_of: :project
|
|
13
|
-
has_many :users, through: :user_project_jobs, inverse_of: :projects
|
|
14
|
-
accepts_nested_attributes_for :user_project_jobs, allow_destroy: true
|
|
15
|
-
|
|
16
|
-
has_many :teams, dependent: :destroy, inverse_of: :project
|
|
17
|
-
accepts_nested_attributes_for :teams, allow_destroy: true
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
end
|
|
1
|
+
class Project < AbstractAdapter
|
|
2
|
+
belongs_to :owner, foreign_key: :owner_id, class_name: 'Company'
|
|
3
|
+
|
|
4
|
+
has_many :roles, as: :ownable
|
|
5
|
+
has_many :admins, through: :roles, source: :user
|
|
6
|
+
accepts_nested_attributes_for :roles, allow_destroy: true
|
|
7
|
+
|
|
8
|
+
has_many :project_jobs, dependent: :destroy, inverse_of: :project
|
|
9
|
+
has_many :jobs, through: :project_jobs
|
|
10
|
+
accepts_nested_attributes_for :project_jobs, allow_destroy: true
|
|
11
|
+
|
|
12
|
+
has_many :user_project_jobs, dependent: :destroy, inverse_of: :project
|
|
13
|
+
has_many :users, through: :user_project_jobs, inverse_of: :projects
|
|
14
|
+
accepts_nested_attributes_for :user_project_jobs, allow_destroy: true
|
|
15
|
+
|
|
16
|
+
has_many :teams, dependent: :destroy, inverse_of: :project
|
|
17
|
+
accepts_nested_attributes_for :teams, allow_destroy: true
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
class ProjectJob < AbstractAdapter
|
|
2
|
-
belongs_to :project
|
|
3
|
-
belongs_to :job
|
|
4
|
-
|
|
5
|
-
delegate :title, to: :job
|
|
6
|
-
|
|
7
|
-
end
|
|
1
|
+
class ProjectJob < AbstractAdapter
|
|
2
|
+
belongs_to :project
|
|
3
|
+
belongs_to :job
|
|
4
|
+
|
|
5
|
+
delegate :title, to: :job
|
|
6
|
+
|
|
7
|
+
end
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
class Role < AbstractAdapter
|
|
2
|
-
belongs_to :user
|
|
3
|
-
belongs_to :ownable, polymorphic: true
|
|
4
|
-
|
|
5
|
-
validates_uniqueness_of :user_id, scope: [:ownable_type,:ownable_id], unless: Proc.new {|u| u.user_id.nil? }, message: "user has already been assigned that role"
|
|
6
|
-
validates_inclusion_of :ownable_type, in: ['Company', 'Project']
|
|
7
|
-
|
|
8
|
-
delegate :email, to: :user, allow_nil: true
|
|
9
|
-
def attributes
|
|
10
|
-
scuper.merge(email: email)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def self.ownable_assign_options(model=nil)
|
|
14
|
-
(Company.all + Project.all).map { |i| [ "#{i.class}: #{i.name}", "#{i.class}-#{i.id}"] }
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def ownable_assign
|
|
18
|
-
ownable.present? ? "#{ownable_type}-#{ownable_id}" : nil
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def ownable_assign=(value)
|
|
22
|
-
self.ownable_type,self.ownable_id = value.split('-')
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
end
|
|
1
|
+
class Role < AbstractAdapter
|
|
2
|
+
belongs_to :user
|
|
3
|
+
belongs_to :ownable, polymorphic: true
|
|
4
|
+
|
|
5
|
+
validates_uniqueness_of :user_id, scope: [:ownable_type,:ownable_id], unless: Proc.new {|u| u.user_id.nil? }, message: "user has already been assigned that role"
|
|
6
|
+
validates_inclusion_of :ownable_type, in: ['Company', 'Project']
|
|
7
|
+
|
|
8
|
+
delegate :email, to: :user, allow_nil: true
|
|
9
|
+
def attributes
|
|
10
|
+
scuper.merge(email: email)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.ownable_assign_options(model=nil)
|
|
14
|
+
(Company.all + Project.all).map { |i| [ "#{i.class}: #{i.name}", "#{i.class}-#{i.id}"] }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def ownable_assign
|
|
18
|
+
ownable.present? ? "#{ownable_type}-#{ownable_id}" : nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def ownable_assign=(value)
|
|
22
|
+
self.ownable_type,self.ownable_id = value.split('-')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
class Team < AbstractAdapter
|
|
2
|
-
belongs_to :project
|
|
3
|
-
belongs_to :creator, class_name: 'User'
|
|
4
|
-
|
|
5
|
-
has_many :team_users, inverse_of: :team
|
|
6
|
-
has_many :users, through: :team_users
|
|
7
|
-
accepts_nested_attributes_for :team_users, allow_destroy: true
|
|
8
|
-
|
|
9
|
-
end
|
|
1
|
+
class Team < AbstractAdapter
|
|
2
|
+
belongs_to :project
|
|
3
|
+
belongs_to :creator, class_name: 'User'
|
|
4
|
+
|
|
5
|
+
has_many :team_users, inverse_of: :team
|
|
6
|
+
has_many :users, through: :team_users
|
|
7
|
+
accepts_nested_attributes_for :team_users, allow_destroy: true
|
|
8
|
+
|
|
9
|
+
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
class TeamUser < AbstractAdapter
|
|
2
|
-
belongs_to :user
|
|
3
|
-
belongs_to :team
|
|
4
|
-
|
|
5
|
-
validate :user_on_project
|
|
6
|
-
|
|
7
|
-
def user_on_project
|
|
8
|
-
unless user && team && user.projects.include?(team.project)
|
|
9
|
-
errors.add(:user, "#{user.try(:name)} is not on the #{team.try(:project).try(:name)} project")
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
end
|
|
1
|
+
class TeamUser < AbstractAdapter
|
|
2
|
+
belongs_to :user
|
|
3
|
+
belongs_to :team
|
|
4
|
+
|
|
5
|
+
validate :user_on_project
|
|
6
|
+
|
|
7
|
+
def user_on_project
|
|
8
|
+
unless user && team && user.projects.include?(team.project)
|
|
9
|
+
errors.add(:user, "#{user.try(:name)} is not on the #{team.try(:project).try(:name)} project")
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
class User < AbstractAdapter
|
|
2
|
-
# Include default devise modules. Others available are:
|
|
3
|
-
# :confirmable, :lockable, :timeoutable and :omniauthable
|
|
4
|
-
devise :database_authenticatable, :registerable, :confirmable,
|
|
5
|
-
:recoverable, :rememberable, :trackable, :validatable, :lockable
|
|
6
|
-
|
|
7
|
-
scope :active, -> { where(:locked_at => nil) }
|
|
8
|
-
scope :inactive, -> { where('locked_at is not null') }
|
|
9
|
-
|
|
10
|
-
has_many :user_locations, dependent: :destroy
|
|
11
|
-
|
|
12
|
-
has_many :user_project_jobs, dependent: :destroy, inverse_of: :user
|
|
13
|
-
has_many :jobs, through: :user_project_jobs, inverse_of: :users
|
|
14
|
-
has_many :projects, through: :user_project_jobs, inverse_of: :users
|
|
15
|
-
accepts_nested_attributes_for :user_project_jobs
|
|
16
|
-
|
|
17
|
-
before_validation :set_default_password_from_project, on: :create
|
|
18
|
-
|
|
19
|
-
has_many :team_users
|
|
20
|
-
has_many :teams, through: :team_users
|
|
21
|
-
|
|
22
|
-
has_many :roles, dependent: :destroy, inverse_of: :user
|
|
23
|
-
accepts_nested_attributes_for :roles, allow_destroy: true
|
|
24
|
-
has_many :admin_companies, through: :roles, source: :ownable, source_type: Company
|
|
25
|
-
has_many :admin_projects, through: :roles, source: :ownable, source_type: Project
|
|
26
|
-
|
|
27
|
-
def all_admin_projects # aggregate companies' projects with project admin roles
|
|
28
|
-
(admin_companies.map(&:projects)+admin_projects).flatten
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def admin?(record)
|
|
32
|
-
roles.detect{|r| r.ownable == record }.present?
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def company_admin? # an admin of any company
|
|
36
|
-
roles.detect{|r| r.ownable_type == 'Company' }.present?
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def project_admin? # an admin of any project
|
|
40
|
-
company_admin? || roles.detect{|r| r.ownable_type == 'Project' }.present?
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def set_default_password_from_project
|
|
45
|
-
self.password = user_project_jobs.first.try(:project).try(:default_password) if password.blank?
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def name
|
|
49
|
-
[first_name,last_name].delete_if(&:blank?).join(' ')
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def avatar_url(size='medium')
|
|
53
|
-
avatar.try(:file).try(:url,size)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def self.attribute_param_types
|
|
57
|
-
{ "skip_confirmation_email" => Virtus::Attribute::Boolean }
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def skip_confirmation_email=(s)
|
|
61
|
-
return unless s.to_s == "true"
|
|
62
|
-
# skip_confirmation! does not work with update_attributes, a work-around:
|
|
63
|
-
self.update_column(:email, email) && self.reload if self.valid? && self.id
|
|
64
|
-
# devise: confirm the user without requiring a confirmation email
|
|
65
|
-
self.skip_confirmation!
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
end
|
|
1
|
+
class User < AbstractAdapter
|
|
2
|
+
# Include default devise modules. Others available are:
|
|
3
|
+
# :confirmable, :lockable, :timeoutable and :omniauthable
|
|
4
|
+
devise :database_authenticatable, :registerable, :confirmable,
|
|
5
|
+
:recoverable, :rememberable, :trackable, :validatable, :lockable
|
|
6
|
+
|
|
7
|
+
scope :active, -> { where(:locked_at => nil) }
|
|
8
|
+
scope :inactive, -> { where('locked_at is not null') }
|
|
9
|
+
|
|
10
|
+
has_many :user_locations, dependent: :destroy
|
|
11
|
+
|
|
12
|
+
has_many :user_project_jobs, dependent: :destroy, inverse_of: :user
|
|
13
|
+
has_many :jobs, through: :user_project_jobs, inverse_of: :users
|
|
14
|
+
has_many :projects, through: :user_project_jobs, inverse_of: :users
|
|
15
|
+
accepts_nested_attributes_for :user_project_jobs
|
|
16
|
+
|
|
17
|
+
before_validation :set_default_password_from_project, on: :create
|
|
18
|
+
|
|
19
|
+
has_many :team_users
|
|
20
|
+
has_many :teams, through: :team_users
|
|
21
|
+
|
|
22
|
+
has_many :roles, dependent: :destroy, inverse_of: :user
|
|
23
|
+
accepts_nested_attributes_for :roles, allow_destroy: true
|
|
24
|
+
has_many :admin_companies, through: :roles, source: :ownable, source_type: 'Company'
|
|
25
|
+
has_many :admin_projects, through: :roles, source: :ownable, source_type: 'Project'
|
|
26
|
+
|
|
27
|
+
def all_admin_projects # aggregate companies' projects with project admin roles
|
|
28
|
+
(admin_companies.map(&:projects)+admin_projects).flatten
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def admin?(record)
|
|
32
|
+
roles.detect{|r| r.ownable == record }.present?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def company_admin? # an admin of any company
|
|
36
|
+
roles.detect{|r| r.ownable_type == 'Company' }.present?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def project_admin? # an admin of any project
|
|
40
|
+
company_admin? || roles.detect{|r| r.ownable_type == 'Project' }.present?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def set_default_password_from_project
|
|
45
|
+
self.password = user_project_jobs.first.try(:project).try(:default_password) if password.blank?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def name
|
|
49
|
+
[first_name,last_name].delete_if(&:blank?).join(' ')
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def avatar_url(size='medium')
|
|
53
|
+
avatar.try(:file).try(:url,size)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.attribute_param_types
|
|
57
|
+
{ "skip_confirmation_email" => Virtus::Attribute::Boolean }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def skip_confirmation_email=(s)
|
|
61
|
+
return unless s.to_s == "true"
|
|
62
|
+
# skip_confirmation! does not work with update_attributes, a work-around:
|
|
63
|
+
self.update_column(:email, email) && self.reload if self.valid? && self.id
|
|
64
|
+
# devise: confirm the user without requiring a confirmation email
|
|
65
|
+
self.skip_confirmation!
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
class UserLocation < AbstractAdapter
|
|
2
|
-
belongs_to :user
|
|
3
|
-
belongs_to :location
|
|
4
|
-
belongs_to :detectable, polymorphic: true
|
|
5
|
-
|
|
6
|
-
validates_inclusion_of :detectable_type, in: %w(LocationBeacon LocationGps)
|
|
7
|
-
|
|
8
|
-
default_scope { includes(:detectable).order("created_at desc") }
|
|
9
|
-
|
|
10
|
-
def coords=(c) # convenience method to set coordinates by an array of [lat,lng,alt]
|
|
11
|
-
self.lat = c[0]
|
|
12
|
-
self.lng = c[1]
|
|
13
|
-
self.alt = c[2]
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def beacon
|
|
17
|
-
detectable.is_a?(LocationBeacon) ? detectable : {}
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def distance
|
|
21
|
-
if location.gps && lat && lng
|
|
22
|
-
location.gps.distance_from(lat,lng)
|
|
23
|
-
else
|
|
24
|
-
nil
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
end
|
|
1
|
+
class UserLocation < AbstractAdapter
|
|
2
|
+
belongs_to :user
|
|
3
|
+
belongs_to :location
|
|
4
|
+
belongs_to :detectable, polymorphic: true
|
|
5
|
+
|
|
6
|
+
validates_inclusion_of :detectable_type, in: %w(LocationBeacon LocationGps)
|
|
7
|
+
|
|
8
|
+
default_scope { includes(:detectable).order("created_at desc") }
|
|
9
|
+
|
|
10
|
+
def coords=(c) # convenience method to set coordinates by an array of [lat,lng,alt]
|
|
11
|
+
self.lat = c[0]
|
|
12
|
+
self.lng = c[1]
|
|
13
|
+
self.alt = c[2]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def beacon
|
|
17
|
+
detectable.is_a?(LocationBeacon) ? detectable : {}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def distance
|
|
21
|
+
if location.gps && lat && lng
|
|
22
|
+
location.gps.distance_from(lat,lng)
|
|
23
|
+
else
|
|
24
|
+
nil
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
class UserProjectJob < AbstractAdapter
|
|
2
|
-
belongs_to :user, inverse_of: :user_project_jobs
|
|
3
|
-
belongs_to :project, inverse_of: :user_project_jobs
|
|
4
|
-
belongs_to :job, inverse_of: :user_project_jobs
|
|
5
|
-
|
|
6
|
-
validates_inclusion_of :job, in: proc {|r| r.project.try(:jobs) || [] }
|
|
7
|
-
|
|
8
|
-
delegate :email, :avatar_url, to: :user
|
|
9
|
-
delegate :title, to: :job
|
|
10
|
-
delegate :name, to: :project
|
|
11
|
-
|
|
12
|
-
def self.options_for_job(project=nil)
|
|
13
|
-
project.jobs
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
end
|
|
1
|
+
class UserProjectJob < AbstractAdapter
|
|
2
|
+
belongs_to :user, inverse_of: :user_project_jobs
|
|
3
|
+
belongs_to :project, inverse_of: :user_project_jobs
|
|
4
|
+
belongs_to :job, inverse_of: :user_project_jobs
|
|
5
|
+
|
|
6
|
+
validates_inclusion_of :job, in: proc {|r| r.project.try(:jobs) || [] }
|
|
7
|
+
|
|
8
|
+
delegate :email, :avatar_url, to: :user
|
|
9
|
+
delegate :title, to: :job
|
|
10
|
+
delegate :name, to: :project
|
|
11
|
+
|
|
12
|
+
def self.options_for_job(project=nil)
|
|
13
|
+
project.jobs
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>Dummy</title>
|
|
5
|
-
<%= stylesheet_link_tag 'application', media: 'all', skip_pipeline: true %>
|
|
6
|
-
<%= csrf_meta_tags %>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
|
|
10
|
-
<%= yield %>
|
|
11
|
-
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Dummy</title>
|
|
5
|
+
<%= stylesheet_link_tag 'application', media: 'all', skip_pipeline: true %>
|
|
6
|
+
<%= csrf_meta_tags %>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
|
|
10
|
+
<%= yield %>
|
|
11
|
+
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
data/spec/dummy/bin/bundle
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
|
3
|
-
load Gem.bin_path('bundler', 'bundle')
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
|
3
|
+
load Gem.bin_path('bundler', 'bundle')
|
data/spec/dummy/bin/rails
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
|
3
|
-
require_relative '../config/boot'
|
|
4
|
-
require 'rails/commands'
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
|
3
|
+
require_relative '../config/boot'
|
|
4
|
+
require 'rails/commands'
|
data/spec/dummy/bin/rake
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
require_relative '../config/boot'
|
|
3
|
-
require 'rake'
|
|
4
|
-
Rake.application.run
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require_relative '../config/boot'
|
|
3
|
+
require 'rake'
|
|
4
|
+
Rake.application.run
|