diff --git a/Gemfile b/Gemfile index 4f9c7b50a..938999574 100644 --- a/Gemfile +++ b/Gemfile @@ -19,7 +19,8 @@ gem 'apollo-tracing', '~> 1.3.0' # Cortex-specific gem 'cortex-exceptions', '= 0.0.4' -gem 'cortex-plugins-core', '= 2.1.1' + +gem 'cortex-plugins-core', git: 'https://github.com/cortex-cms/cortex-plugins-core.git' , branch: 'CE-738/Refactor-Tree-Field-Type' #'= 2.1.1' # Service Layer gem 'dry-types', '~> 0.12.2' @@ -43,7 +44,6 @@ gem 'elasticsearch-dsl', '~> 0.1' gem 'paranoia', '~> 2.4' gem 'pg', '~> 0.21.0' gem 'redis-rails', '~> 5.0' -gem 'pomona', '~> 0.7' gem 'transitions', '~> 1.2', require: %w(transitions active_model/transitions) # Middleware diff --git a/Gemfile.lock b/Gemfile.lock index 7394e47c2..69fa81881 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,23 @@ +GIT + remote: https://github.com/cortex-cms/cortex-plugins-core.git + revision: c793b4c25bff15e53e7f4594826dc4514b6fe262 + branch: CE-738/Refactor-Tree-Field-Type + specs: + cortex-plugins-core (2.1.1) + aws-sdk-s3 (~> 1.5) + cells (~> 4.1) + cells-haml (~> 0.0) + cells-rails (~> 0.0) + fastimage (~> 2.1) + image_optim (~> 0.25) + image_optim_pack (~> 0.5) + image_processing (~> 0.4) + jsonb_accessor (~> 1.0) + mimemagic (~> 0.3) + mini_magick (~> 4.8) + rails (>= 5) + shrine (~> 2.7) + GEM remote: https://rubygems.org/ specs: @@ -48,15 +68,15 @@ GEM execjs awesome_nested_set (3.1.3) activerecord (>= 4.0.0, < 5.2) - aws-partitions (1.35.0) - aws-sdk-core (3.7.0) + aws-partitions (1.67.0) + aws-sdk-core (3.17.0) aws-partitions (~> 1.0) aws-sigv4 (~> 1.0) jmespath (~> 1.0) - aws-sdk-kms (1.3.0) + aws-sdk-kms (1.5.0) aws-sdk-core (~> 3) aws-sigv4 (~> 1.0) - aws-sdk-s3 (1.6.0) + aws-sdk-s3 (1.8.2) aws-sdk-core (~> 3) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.0) @@ -105,20 +125,6 @@ GEM concurrent-ruby (1.0.5) connection_pool (2.2.1) cortex-exceptions (0.0.4) - cortex-plugins-core (2.1.1) - aws-sdk-s3 (~> 1.5) - cells (~> 4.1) - cells-haml (~> 0.0) - cells-rails (~> 0.0) - fastimage (~> 2.1) - image_optim (~> 0.25) - image_optim_pack (~> 0.5) - image_processing (~> 0.4) - jsonb_accessor (~> 1.0) - mimemagic (~> 0.3) - mini_magick (~> 4.8) - rails (>= 5) - shrine (~> 2.7) crass (1.0.3) database_cleaner (1.6.2) debug_inspector (0.0.3) @@ -138,7 +144,7 @@ GEM dotenv-rails (2.2.1) dotenv (= 2.2.1) railties (>= 3.2, < 5.2) - down (4.1.1) + down (4.2.1) dry-configurable (0.7.0) concurrent-ruby (~> 1.0) dry-container (0.6.0) @@ -200,7 +206,7 @@ GEM erubi (1.7.0) erubis (2.7.0) execjs (2.7.0) - exifr (1.3.2) + exifr (1.3.3) factory_girl (4.9.0) activesupport (>= 3.0.0) factory_girl_rails (4.9.0) @@ -210,7 +216,7 @@ GEM i18n (~> 0.5) faraday (0.13.1) multipart-post (>= 1.2, < 3) - fastimage (2.1.0) + fastimage (2.1.1) ffi (1.9.18) flipper (0.11.0) flipper-active_record (0.11.0) @@ -265,13 +271,13 @@ GEM i18n (0.9.1) concurrent-ruby (~> 1.0) ice_nine (0.11.2) - image_optim (0.26.0) + image_optim (0.26.1) exifr (~> 1.2, >= 1.2.2) fspath (~> 3.0) image_size (~> 1.5) in_threads (~> 1.3) progress (~> 3.0, >= 3.0.1) - image_optim_pack (0.5.0.20171101) + image_optim_pack (0.5.0.20180124) fspath (>= 2.1, < 4) image_optim (~> 0.19) image_processing (0.4.5) @@ -367,7 +373,6 @@ GEM capybara (~> 2.1) cliver (~> 0.3.1) websocket-driver (>= 0.2.0) - pomona (0.7.0) progress (3.4.0) pry (0.10.4) coderay (~> 1.1.0) @@ -502,7 +507,7 @@ GEM shellany (0.0.1) shoulda-matchers (3.1.2) activesupport (>= 4.0.0) - shrine (2.8.0) + shrine (2.9.0) down (~> 4.1) sidekiq (5.0.5) concurrent-ruby (~> 1.0) @@ -574,7 +579,7 @@ DEPENDENCIES cells-rails (~> 0.0.8) codeclimate-test-reporter cortex-exceptions (= 0.0.4) - cortex-plugins-core (= 2.1.1) + cortex-plugins-core! database_cleaner devise (~> 4.3.0) dialog-polyfill-rails (~> 0.4.5) @@ -620,7 +625,6 @@ DEPENDENCIES pg (~> 0.21.0) phantomjs (~> 2.1) poltergeist - pomona (~> 0.7) pry-nav pry-rails pry-remote diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 1417c494e..8277d49fc 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -18,5 +18,6 @@ //= require flash //= require media_dialogs //= require quick_links +//= require example_tree_select // require turbolinks # temporarily disabled diff --git a/app/assets/javascripts/example_tree_select.js b/app/assets/javascripts/example_tree_select.js new file mode 100644 index 000000000..e2f020a0c --- /dev/null +++ b/app/assets/javascripts/example_tree_select.js @@ -0,0 +1,12 @@ + +function TreeBranchClicked(nested_id, target) { + var checked = $(target).find('input[type="checkbox"]')[0].checked; + + $(nested_id).find('input[type="checkbox"]').prop('checked', checked) + + if (checked === true) { + $(nested_id).find('label').addClass('is-checked'); + } else { + $(nested_id).find('label').removeClass('is-checked'); + } +} diff --git a/app/assets/stylesheets/components/form.scss b/app/assets/stylesheets/components/form.scss index 011f8d9e5..9648a8bf6 100644 --- a/app/assets/stylesheets/components/form.scss +++ b/app/assets/stylesheets/components/form.scss @@ -43,3 +43,7 @@ form { color: $color-grey; font-size: $base-font-size * 1.25; } + +.nested-checkbox-group { + padding-left: 30px; +} diff --git a/config/initializers/tree_builder.rb b/config/initializers/tree_builder.rb new file mode 100644 index 000000000..bf4b7bde5 --- /dev/null +++ b/config/initializers/tree_builder.rb @@ -0,0 +1,51 @@ +require 'securerandom' + +class TreeBuilder + attr_accessor :target_node + attr_reader :head, :tree_fields + + def initialize + @head = Hashr.new children: [] + @tree_fields = {} + @target_node = @head + end + + def self.generate_id + SecureRandom.hex 6 + end + + def self.node value + Hashr.new name: value, value: value.downcase, children: [] + end + + def find_node node_value + target_node.children.each do |id| + if tree_fields[id].value == node_value || tree_fields[id].name == node_value + @target_node = tree_fields[id] + end + end + self + end + + def add_value value + field_id = TreeBuilder.generate_id + tree_fields[field_id] = TreeBuilder.node value + @target_node.children << field_id + @target_node = head + end + + def tree_fields_hash + @tree_fields_hash ||= tree_fields.keys.inject({}) do |lookup, field_key| + lookup[field_key] = tree_fields[field_key].to_h + lookup + end + end + + def tree_data + { + head: head[:children], + tree_fields: tree_fields_hash, + data: tree_fields_hash + } + end +end diff --git a/lib/tasks/employer/blog.rake b/lib/tasks/employer/blog.rake index 9192982dd..8293a7f1e 100644 --- a/lib/tasks/employer/blog.rake +++ b/lib/tasks/employer/blog.rake @@ -7,34 +7,88 @@ namespace :employer do example_tenant = Tenant.find_by_name('Example') def research_tree - tree = Tree.new - tree.add_node({name: "CB Research"}) - tree.add_node({name: "Third Party Research"}) + tree = TreeBuilder.new + tree.add_value("CB Research") + tree.add_value("Third Party Research") - tree + tree.tree_data end def category_tree - tree = Tree.new - tree.add_node({ name: "Product News" }) - tree.add_node({ name: "Company News, Research and Trends" }) - tree.add_node({ name: "Client Success Stories" }) - tree.add_node({ name: "Recruiting Solutions" }) - tree.add_node({ name: "Employment Screening" }) - tree.add_node({ name: "Human Capital Management" }) + tree = TreeBuilder.new + tree.add_value("Product News") + tree.add_value("Company News, Research and Trends") + tree.add_value("Client Success Stories") + tree.add_value("Recruiting Solutions") + tree.add_value("Employment Screening") + tree.add_value("Human Capital Management") - tree + tree.tree_data end + def professions_tree + tree = TreeBuilder.new + tree.add_value('Finance') + tree.find_node('Finance').add_value("Accountant") + tree.find_node('Finance').add_value("Auditor") + tree.find_node('Finance').add_value("That Guy") + tree.add_value('Management') + tree.find_node('Management').add_value("Human Resources") + tree.find_node('Management').add_value("Product Owner") + tree.add_value("Nurse") + tree.add_value("Doctor") + tree.find_node("Doctor").add_value('Oncologist') + tree.find_node("Doctor").add_value('Love') + tree.find_node("Doctor").add_value('Pepper') + tree.add_value("Software Engineer") + tree.find_node("Software Engineer").add_value('Database Admin') + tree.find_node("Software Engineer").add_value('Gaming') + tree.find_node("Software Engineer").add_value('Web') + tree.find_node("Software Engineer").find_node('Web').add_value("Front End") + tree.find_node("Software Engineer").find_node('Web').add_value("Back End") + tree.find_node("Software Engineer").find_node('Web').add_value("Fullstack") + + tree.tree_data + end + + def industries_tree + tree = TreeBuilder.new + tree.add_value('General') + tree.add_value('All') + tree.find_node('All').add_value('Finance') + tree.find_node('All').find_node('Finance').add_value("Accounting") + tree.find_node('All').find_node('Finance').add_value("Auditing") + tree.find_node('All').find_node('Finance').add_value("Trading") + tree.find_node('All').add_value('Medical') + tree.find_node('All').find_node('Medical').add_value("Nursing") + tree.find_node('All').find_node('Medical').add_value("Surgery") + tree.find_node('All').find_node('Medical').add_value("Phramacy") + tree.find_node('All').add_value('Management') + tree.find_node('All').find_node('Management').add_value("Human Resources") + tree.find_node('All').find_node('Management').add_value("Product Owner") + tree.find_node('All').add_value('Manufacturing') + tree.find_node('All').add_value('Technology') + tree.find_node('All').find_node('Technology').add_value('Web and Applications') + tree.find_node('All').find_node('Technology').add_value('Video Games') + tree.find_node('All').add_value('Education') + tree.find_node('All').find_node('Education').add_value('K-12') + tree.find_node('All').find_node('Education').add_value('Collegiate') + tree.find_node('All').add_value('Entertainment') + + tree.tree_data + end + + + def persona_tree - tree = Tree.new - tree.add_node({name: "General Audience"}) - tree.add_node({name: "Recruiters"}) - tree.add_node({name: "Sourcers"}) - tree.add_node({name: "Managers/Directors"}) - tree.add_node({name: "C-Level"}) + tree = TreeBuilder.new + tree.add_value("General Audience") + tree.add_value("Recruiters") + tree.add_value("Sourcers") + tree.add_value("Managers/Directors") + tree.add_value("C-Level") - tree + tree.tree_data end puts "Creating Employer Blog ContentType..." @@ -68,9 +122,11 @@ namespace :employer do blog.fields.new(name: 'No ODP', name_id: 'no_odp', field_type: 'boolean_field_type') blog.fields.new(name: 'No Archive', name_id: 'no_archive', field_type: 'boolean_field_type') blog.fields.new(name: 'No Image Index', name_id: 'no_image_index', field_type: 'boolean_field_type') - blog.fields.new(name: 'Categories', name_id: 'categories', field_type: 'tree_field_type', metadata: {allowed_values: category_tree}, validations: {maximum: 2, minimum: 1}) - blog.fields.new(name: 'Research', name_id: 'research', field_type: 'tree_field_type', metadata: {allowed_values: research_tree}, validations: {minimum: 1}) + blog.fields.new(name: 'Categories', name_id: 'categories', field_type: 'tree_field_type', metadata: {allowed_values: category_tree}) + blog.fields.new(name: 'Research', name_id: 'research', field_type: 'tree_field_type', metadata: {allowed_values: research_tree}) blog.fields.new(name: 'Persona', name_id: 'persona', field_type: 'tree_field_type', metadata: {allowed_values: persona_tree}) + blog.fields.new(name: 'Profession', name_id: 'profession', field_type: 'tree_field_type', metadata: {allowed_values: professions_tree}, validations: {minimum: 1}) + blog.fields.new(name: 'Industries', name_id: 'industries', field_type: 'tree_field_type', metadata: {allowed_values: industries_tree}) blog.fields.new(name: 'Featured Image', name_id: 'featured_image', field_type: 'content_item_field_type', metadata: { field_name: 'Asset' @@ -170,7 +226,18 @@ namespace :employer do ] }, { + "heading": "Industries (Optional Heading)", "grid_width": 4, + "elements": [ + { + "id": blog.fields.find_by_name('Industries').id, + "render_method": "checkboxes", + "tooltip": "Please select related Industries." + } + ] + }, + { + "grid_width": 2, "elements": [ { "id": blog.fields.find_by_name('Persona').id, @@ -180,7 +247,7 @@ namespace :employer do ] }, { - "grid_width": 4, + "grid_width": 2, "elements": [ { "id": blog.fields.find_by_name('Research').id,