diff --git a/.eslintrc.json b/.eslintrc.json index 1821b4e..248fe55 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,7 +3,10 @@ "rules": {}, "parserOptions": { "ecmaVersion": 2018, - "sourceType": "module" + "sourceType": "module", + "ecmaFeatures": { + "jsx": true + } }, "env": { "browser": true, diff --git a/app/controllers/group_types_controller.rb b/app/controllers/group_types_controller.rb index 8b11f48..ab90686 100644 --- a/app/controllers/group_types_controller.rb +++ b/app/controllers/group_types_controller.rb @@ -19,7 +19,8 @@ def create @group_type = GroupType.new(group_type_params) if @group_type.save - redirect_to group_types_path, notice: 'Group type was successfully created.' + redirect_to group_types_path, + notice: 'Group type was successfully created.' else render :new end @@ -35,7 +36,8 @@ def update def destroy @group_type.destroy! - redirect_to group_types_url, notice: 'Group type was successfully destroyed.' + redirect_to group_types_url, + notice: 'Group type was successfully destroyed.' end private diff --git a/app/controllers/group_websites_controller.rb b/app/controllers/group_websites_controller.rb index 5bb0bb1..0dd52be 100644 --- a/app/controllers/group_websites_controller.rb +++ b/app/controllers/group_websites_controller.rb @@ -21,7 +21,8 @@ def create @group_website = @group.websites.new(group_website_params) if @group_website.save - redirect_to group_group_websites_url(@group), notice: 'Group website was successfully created.' + redirect_to group_group_websites_url(@group), + notice: 'Group website was successfully created.' else render :new end @@ -29,7 +30,8 @@ def create def update if @group_website.update(group_website_params) - redirect_to [@group, @group_website], notice: 'Group website was successfully updated.' + redirect_to [@group, @group_website], + notice: 'Group website was successfully updated.' else render :edit end @@ -37,7 +39,8 @@ def update def destroy @group_website.destroy - redirect_to group_group_websites_url(@group), notice: 'Group website was successfully destroyed.' + redirect_to group_group_websites_url(@group), + notice: 'Group website was successfully destroyed.' end private diff --git a/app/controllers/initiative_statuses_controller.rb b/app/controllers/initiative_statuses_controller.rb index c21e8d4..5e05f1a 100644 --- a/app/controllers/initiative_statuses_controller.rb +++ b/app/controllers/initiative_statuses_controller.rb @@ -19,7 +19,8 @@ def create @initiative_status = InitiativeStatus.new(initiative_status_params) if @initiative_status.save - redirect_to initiative_statuses_path, notice: 'Initiative status was successfully created.' + redirect_to initiative_statuses_path, + notice: 'Initiative status was successfully created.' else render :new end @@ -27,7 +28,8 @@ def create def update if @initiative_status.update(initiative_status_params) - redirect_to @initiative_status, notice: 'Initiative status was successfully updated.' + redirect_to @initiative_status, + notice: 'Initiative status was successfully updated.' else render :edit end @@ -35,7 +37,8 @@ def update def destroy @initiative_status.destroy - redirect_to initiative_statuses_url, notice: 'Initiative status was successfully destroyed.' + redirect_to initiative_statuses_url, + notice: 'Initiative status was successfully destroyed.' end private diff --git a/app/controllers/initiatives_controller.rb b/app/controllers/initiatives_controller.rb index 64fee09..b93bfa8 100644 --- a/app/controllers/initiatives_controller.rb +++ b/app/controllers/initiatives_controller.rb @@ -54,6 +54,8 @@ def set_edit_data InitiativeStatus.all.map do |initiative_status| [initiative_status.name, initiative_status.id] end + + @taxonomy_hierarchy_json = Solution.hierarchy.to_json end # rubocop:disable Metrics/MethodLength @@ -75,7 +77,8 @@ def initiative_params :partner_groups_role, :status_id, :gdpr, - :gdpr_email_verified + :gdpr_email_verified, + solutions_attributes: %i[solution_id solution_class_id] ) end # rubocop:enable Metrics/MethodLength diff --git a/app/models/initiative.rb b/app/models/initiative.rb index b374e00..5087d4a 100644 --- a/app/models/initiative.rb +++ b/app/models/initiative.rb @@ -6,6 +6,8 @@ class Initiative < ApplicationRecord delegate :name, prefix: true, to: :status delegate :name, prefix: true, to: :lead_group after_initialize :set_default_location + has_many :solutions, class_name: 'InitiativeSolution', dependent: :destroy + accepts_nested_attributes_for :solutions def set_default_location self.latitude ||= 51.742 diff --git a/app/models/initiative_solution.rb b/app/models/initiative_solution.rb new file mode 100644 index 0000000..941d06a --- /dev/null +++ b/app/models/initiative_solution.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class InitiativeSolution < ApplicationRecord + belongs_to :solution + belongs_to :solution_class + belongs_to :initiative +end diff --git a/app/models/initiative_status.rb b/app/models/initiative_status.rb index d745acf..0380461 100644 --- a/app/models/initiative_status.rb +++ b/app/models/initiative_status.rb @@ -1,4 +1,3 @@ # frozen_string_literal: true -class InitiativeStatus < ApplicationRecord -end +class InitiativeStatus < ApplicationRecord; end diff --git a/app/models/solution.rb b/app/models/solution.rb index 6b48e15..525c9d7 100644 --- a/app/models/solution.rb +++ b/app/models/solution.rb @@ -1,5 +1,62 @@ # frozen_string_literal: true class Solution < ApplicationRecord - # has_many :solution_classes + has_many :solution_solution_classes, dependent: :destroy + + def self.deep_load_solutions + Solution.all.includes( + solution_solution_classes: { solution_class: { theme: :sector } } + ) + end + + def self.hierarchy + hierarchy = [] + deep_load_solutions.find_each do |s| + s.solution_solution_classes.each do |sc| + sector = populate_sector(hierarchy, sc.solution_class) + theme = populate_theme(sector, sc.solution_class) + solution_class = populate_solution_class(theme, sc.solution_class.name) + populate_solution(solution_class, sc.solution, sc.solution_class) + end + end + hierarchy + end + + def self.populate_sector(hierarchy, solution_class) + name = solution_class.theme.sector.name + sector = hierarchy.select { |s| s[:name] == name }.first + if sector.nil? + sector = { name: name, themes: [] } + hierarchy << sector + end + sector + end + + def self.populate_theme(sector, solution_class) + name = solution_class.theme_name + themes = sector[:themes] + theme = themes.select { |t| t[:name] == name }.first + if theme.nil? + theme = { name: name, classes: [] } + sector[:themes] << theme + end + theme + end + + def self.populate_solution_class(theme, name) + solution_class = theme[:classes].select { |t| t[:name] == name }.first + if solution_class.nil? + solution_class = { name: name, solutions: [] } + theme[:classes] << solution_class + end + solution_class + end + + def self.populate_solution(mapped_solution_class, solution, solution_class) + name = solution.name + solution = { + name: name, solution_class_id: solution_class.id, solution_id: solution.id + } + mapped_solution_class[:solutions] << solution + end end diff --git a/app/models/solution_class.rb b/app/models/solution_class.rb index 5557be4..6d464c3 100644 --- a/app/models/solution_class.rb +++ b/app/models/solution_class.rb @@ -2,4 +2,5 @@ class SolutionClass < ApplicationRecord belongs_to :theme + delegate :name, to: :theme, prefix: true end diff --git a/app/models/tag.rb b/app/models/tag.rb index 5d747aa..03af6bd 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -1,4 +1,3 @@ # frozen_string_literal: true -class Tag < ApplicationRecord -end +class Tag < ApplicationRecord; end diff --git a/app/models/user.rb b/app/models/user.rb index 1828ebd..3567d6c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -8,5 +8,6 @@ class User < ApplicationRecord :recoverable, :rememberable, :validatable - has_many :groups, dependent: :nullify, foreign_key: 'owner_id', inverse_of: :owner + has_many :groups, + dependent: :nullify, foreign_key: 'owner_id', inverse_of: :owner end diff --git a/app/views/initiatives/_form.html.erb b/app/views/initiatives/_form.html.erb index 04655af..a40244b 100644 --- a/app/views/initiatives/_form.html.erb +++ b/app/views/initiatives/_form.html.erb @@ -1,5 +1,7 @@ <% content_for :page_javascript do %> <%= javascript_packs_with_chunks_tag 'initiative_location_picker', 'data-turbolinks-track': 'reload' %> + <%= javascript_packs_with_chunks_tag 'initiative_solution_picker', 'data-turbolinks-track': 'reload' %> + <% end %> <%= form_with(model: initiative, local: true, html: {class: 'FormField-form'}) do |f| %> @@ -20,11 +22,6 @@ <%= f.text_field :name, autofocus: true %> <% end %> - <%= f.form_field :alternative_solution_name do %> - <%= f.label :alternative_solution_name %> - <%= f.text_field :alternative_solution_name %> - <% end %> - <%= f.form_field :summary do %> <%= f.label :summary %> <%= f.text_field :summary %> @@ -92,6 +89,18 @@ <%= f.select :status_id, initiative_statuses %> <% end %> +

Solutions

+ + <%= f.form_field :choose_solution do %> + <%= f.label :choose_solution %> +
+ <% end %> + + <%= f.form_field :alternative_solution_name do %> + <%= f.label :alternative_solution_name %> + <%= f.text_field :alternative_solution_name %> + <% end %> + <%= f.form_field :gdpr do %> <%= f.label :gdpr %> <%= f.check_box :gdpr %> diff --git a/app/views/initiatives/edit.html.erb b/app/views/initiatives/edit.html.erb index 6f590b1..005dc4a 100644 --- a/app/views/initiatives/edit.html.erb +++ b/app/views/initiatives/edit.html.erb @@ -1,6 +1,6 @@

Editing Initiative

-<%= render 'form', initiative: @initiative, groups: @groups, initiative_statuses: @initiative_statuses %> +<%= render 'form', initiative: @initiative, groups: @groups, initiative_statuses: @initiative_statuses, taxonomy_hierarchy_json: @taxonomy_hierarchy_json %> <%= link_to 'Show', @initiative %> | <%= link_to 'Back', initiatives_path %> diff --git a/app/views/initiatives/new.html.erb b/app/views/initiatives/new.html.erb index f1d0bbf..9b16121 100644 --- a/app/views/initiatives/new.html.erb +++ b/app/views/initiatives/new.html.erb @@ -1,5 +1,5 @@

New Initiative

-<%= render 'form', initiative: @initiative, groups: @groups, initiative_statuses: @initiative_statuses %> +<%= render 'form', initiative: @initiative, groups: @groups, initiative_statuses: @initiative_statuses, taxonomy_hierarchy_json: @taxonomy_hierarchy_json %> <%= link_to 'Back', initiatives_path %> diff --git a/babel.config.js b/babel.config.js index 7e880a5..fa6ed76 100644 --- a/babel.config.js +++ b/babel.config.js @@ -34,8 +34,10 @@ module.exports = function(api) { modules: false, exclude: ["transform-typeof-symbol"] } - ] + ], + "babel-preset-hyperdom" ].filter(Boolean), + plugins: [ require("babel-plugin-macros"), require("@babel/plugin-syntax-dynamic-import").default, diff --git a/db/migrate/20191022214904_create_initiative_solutions.rb b/db/migrate/20191022214904_create_initiative_solutions.rb new file mode 100644 index 0000000..2f65c0f --- /dev/null +++ b/db/migrate/20191022214904_create_initiative_solutions.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class CreateInitiativeSolutions < ActiveRecord::Migration[6.0] + def change + create_table :initiative_solutions do |t| + t.references :solution, null: false, foreign_key: true + t.references :solution_class, null: false, foreign_key: true + t.references :initiative, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index d544513..3c0efce 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2019_10_21_195951) do +ActiveRecord::Schema.define(version: 2019_10_22_214904) do # These are extensions that must be enabled in order to support this database enable_extension 'plpgsql' @@ -52,6 +52,19 @@ t.index %w[owner_id], name: 'index_groups_on_owner_id' end + create_table 'initiative_solutions', force: :cascade do |t| + t.bigint 'solution_id', null: false + t.bigint 'solution_class_id', null: false + t.bigint 'initiative_id', null: false + t.datetime 'created_at', precision: 6, null: false + t.datetime 'updated_at', precision: 6, null: false + t.index %w[initiative_id], + name: 'index_initiative_solutions_on_initiative_id' + t.index %w[solution_class_id], + name: 'index_initiative_solutions_on_solution_class_id' + t.index %w[solution_id], name: 'index_initiative_solutions_on_solution_id' + end + create_table 'initiative_statuses', force: :cascade do |t| t.string 'name' t.string 'description' @@ -144,6 +157,9 @@ add_foreign_key 'group_group_types', 'group_types' add_foreign_key 'group_group_types', 'groups' add_foreign_key 'group_websites', 'groups' + add_foreign_key 'initiative_solutions', 'initiatives' + add_foreign_key 'initiative_solutions', 'solution_classes' + add_foreign_key 'initiative_solutions', 'solutions' add_foreign_key 'initiatives', 'groups', column: 'lead_group_id' add_foreign_key 'initiatives', 'initiative_statuses', column: 'status_id' add_foreign_key 'solution_classes', 'themes' diff --git a/frontend/packs/initiative_solution_picker.js b/frontend/packs/initiative_solution_picker.js new file mode 100644 index 0000000..26b0d7d --- /dev/null +++ b/frontend/packs/initiative_solution_picker.js @@ -0,0 +1,287 @@ +import hyperdom from "hyperdom"; + +class SolutionPicker { + constructor({ taxonomy_hierarchy }) { + this.isValid = false; + this.solutions = []; + this.value = ""; + this.results = []; + this.navigation = {}; + this.taxonomy_hierarchy = taxonomy_hierarchy; + } + + render() { + return ( +
+ {this.renderChosenSolutions()} + {this.renderResults()} +
+ ); + } + + navigate({ sector, theme, solutionClass } = {}) { + if (sector) { + this.navigation = { sector }; + return; + } + if (theme) { + this.navigation = { + sector: this.navigation.sector, + theme + }; + return; + } + if (solutionClass) { + this.navigation = { + sector: this.navigation.sector, + theme: this.navigation.theme, + solutionClass + }; + return; + } + this.navigation = {}; + } + + renderResults() { + if (this.value && this.results.length === 0) { + return

No results

; + } + if (this.results.length > 0) { + return ( + + ); + } + if (this.navigation) { + return ( +
+ {this.renderBreadcrumb()} +
+ {this.renderSectors()} + {this.renderThemes()} + {this.renderClasses()} + {this.renderSolutions()} +
+
+ ); + } + } + + renderBreadcrumb() { + const self = this; + function renderSector() { + if (self.navigation.sector) { + return [ +  > , + self.navigate({ sector: self.navigation.sector })} + > + {self.navigation.sector.name} + + ]; + } + } + function renderTheme() { + if (self.navigation.theme) { + return [ +  > , + self.navigate({ theme: self.navigation.theme })}> + {self.navigation.theme.name} + + ]; + } + } + function renderSolutionClass() { + if (self.navigation.solutionClass) { + return [ +  > , + + self.navigate({ solutionClass: self.navigation.solutionClass }) + } + > + {self.navigation.solutionClass.name} + + ]; + } + } + function renderAll() { + return ( + self.navigate()} + > + All + + ); + } + return ( +
+ {renderAll()} + {renderSector()} + {renderTheme()} + {renderSolutionClass()} +
+ ); + } + + renderSectors() { + return ( + + ); + } + + renderThemes() { + if (this.navigation.sector) { + return ( + + ); + } + } + + renderClasses() { + if (this.navigation.theme) { + return ( + + ); + } + } + + renderSolutions() { + if (this.navigation.solutionClass) { + return ( + + ); + } + } + + renderChosenSolutions() { + if (this.solutions.length === 0) { + return ( + + ); + } else { + return ( + + ); + } + } + + addSolution(solution) { + this.solutions.push(solution); + this.value = ""; + this.results = []; + } + + removeSolution(solution) { + const solutionIndex = this.solutions.indexOf(solution); + this.solutions.splice(solutionIndex, 1); + } +} + +window.addEventListener("load", function() { + const taxonomy_hierarchy = JSON.parse( + document.getElementById("taxonomy_hierarchy_json").innerText + ); + hyperdom.append( + document.querySelector("#solution_picker"), + new SolutionPicker({ taxonomy_hierarchy }) + ); +}); diff --git a/frontend/styles/application.css b/frontend/styles/application.css index 42e1d8b..5d9dde7 100644 --- a/frontend/styles/application.css +++ b/frontend/styles/application.css @@ -10,6 +10,7 @@ @import "./components/content"; @import "./components/form-field"; @import "./components/initiative-location-picker"; +@import "./components/initiative-solution-picker"; @font-face { font-family: "fira_sansregular"; diff --git a/frontend/styles/components/initiative-solution-picker.css b/frontend/styles/components/initiative-solution-picker.css new file mode 100644 index 0000000..7fbfc8b --- /dev/null +++ b/frontend/styles/components/initiative-solution-picker.css @@ -0,0 +1,68 @@ + +.AddInitiativeSolution-lookup div { + display: flex; +} + +.AddInitiativeSolution-lookup input { + width: 100%; +} + +.AddInitiativeSolution-breadcrumb { +} + +.AddInitiativeSolution-breadcrumb span { + cursor: pointer; + white-space: nowrap; +} + +.AddInitiativeSolution-groupResults { + flex-direction: column; +} + +.AddInitiativeSolution-groupContainer { + overflow: hidden; +} + +.AddInitiativeSolution-clear { +} + +.AddInitiativeSolution-removeSolution { + float: right; +} + +.AddInitiativeSolution-group { + flex: 10 0 auto; + padding: 2px; +} + +.AddInitiativeSolution-group li, +.AddInitiativeSolution-solutions li { + list-style-type: none; + padding: 3px; +} + +.AddInitiativeSolution-group li:nth-child(even), +.AddInitiativeSolution-solutions li:nth-child(even) { + background-color: #e5e5e5; +} + +.AddInitiativeSolution-solutionSelector li { + cursor: default !important; +} + +.AddInitiativeSolution-addSolution, +.AddInitiativeSolution-removeSolution, +.AddInitiativeSolution-group li { + cursor: pointer; +} + +.AddInitiativeSolution-solutions, +.AddInitiativeSolution-group { + background-color: white; + border: 1px solid; + padding: 2px; +} + +.AddInitiativeSolution-groupSelected { + display: none; +} diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake index fcdd596..a922ee9 100644 --- a/lib/tasks/import.rake +++ b/lib/tasks/import.rake @@ -1,9 +1,10 @@ +# frozen_string_literal: true + require 'csv' namespace :import do - desc 'Run tests with coverage report' + desc 'Import taxonomy from csv' task taxonomy: :environment do - #ap "hello" solutions = CSV.read('./import/taxonomy.csv', headers: true) solutions.each do |line| sector = Sector.find_or_create_by(name: line['sector']) @@ -12,7 +13,5 @@ namespace :import do solution = Solution.find_or_create_by(name: line['solution']) SolutionSolutionClass.create(solution: solution, solution_class: solution_class) end - end end - diff --git a/package.json b/package.json index 5e4f103..79c071f 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,8 @@ "@rails/activestorage": "^6.0.0-alpha", "@rails/ujs": "^6.0.0-alpha", "@rails/webpacker": "^4.0.7", + "babel-preset-hyperdom": "^2.0.0", + "hyperdom": "^2.1.0", "leaflet": "^1.5.1", "leaflet-gesture-handling": "^1.1.8", "leaflet.markercluster": "^1.4.1", diff --git a/test/controllers/group_types_controller_test.rb b/test/controllers/group_types_controller_test.rb index 598cab3..b1727b1 100644 --- a/test/controllers/group_types_controller_test.rb +++ b/test/controllers/group_types_controller_test.rb @@ -3,9 +3,7 @@ require 'test_helper' class GroupTypesControllerTest < ActionDispatch::IntegrationTest - setup do - @group_type = group_types(:one) - end + setup { @group_type = group_types(:one) } test 'should get index' do sign_in_as :georgie @@ -42,7 +40,8 @@ class GroupTypesControllerTest < ActionDispatch::IntegrationTest test 'should update group_type' do sign_in_as :georgie - patch group_type_url(@group_type), params: { group_type: { name: @group_type.name } } + patch group_type_url(@group_type), + params: { group_type: { name: @group_type.name } } assert_redirected_to group_type_url(@group_type) end diff --git a/test/controllers/group_websites_controller_test.rb b/test/controllers/group_websites_controller_test.rb index 85d6637..6005e7e 100644 --- a/test/controllers/group_websites_controller_test.rb +++ b/test/controllers/group_websites_controller_test.rb @@ -23,9 +23,8 @@ class GroupWebsitesControllerTest < ActionDispatch::IntegrationTest test 'should create group_website' do sign_in_as :georgie assert_difference('@group.websites.count') do - post group_group_websites_url(@group), params: { - group_website: { website: 'http://new.website' } - } + post group_group_websites_url(@group), + params: { group_website: { website: 'http://new.website' } } end assert_redirected_to group_group_websites_path(@group) @@ -45,9 +44,12 @@ class GroupWebsitesControllerTest < ActionDispatch::IntegrationTest test 'should update group_website' do sign_in_as :georgie - patch group_group_website_url(@group, @group_website), params: { - group_website: { group: @group_website.group, website: @group_website.website } - } + patch group_group_website_url(@group, @group_website), + params: { + group_website: { + group: @group_website.group, website: @group_website.website + } + } assert_redirected_to group_group_website_url(@group, @group_website) end diff --git a/test/controllers/groups_controller_test.rb b/test/controllers/groups_controller_test.rb index fe2f002..bcd89e0 100644 --- a/test/controllers/groups_controller_test.rb +++ b/test/controllers/groups_controller_test.rb @@ -3,9 +3,7 @@ require 'test_helper' class GroupsControllerTest < ActionDispatch::IntegrationTest - setup do - @group = groups(:one) - end + setup { @group = groups(:one) } test 'should get index' do sign_in_as :georgie @@ -22,18 +20,19 @@ class GroupsControllerTest < ActionDispatch::IntegrationTest test 'should create group' do sign_in_as :georgie assert_difference('Group.count') do - post groups_url, params: { - group: { - abbreviation: @group.abbreviation, - contact_email: @group.contact_email, - contact_name: @group.contact_name, - contact_phone: @group.contact_phone, - gdpr: @group.gdpr, - gdpr_email_verified: @group.gdpr_email_verified, - name: @group.name, - opening_hours: @group.opening_hours - } - } + post groups_url, + params: { + group: { + abbreviation: @group.abbreviation, + contact_email: @group.contact_email, + contact_name: @group.contact_name, + contact_phone: @group.contact_phone, + gdpr: @group.gdpr, + gdpr_email_verified: @group.gdpr_email_verified, + name: @group.name, + opening_hours: @group.opening_hours + } + } end assert_redirected_to groups_path @@ -53,27 +52,26 @@ class GroupsControllerTest < ActionDispatch::IntegrationTest test 'should update group' do sign_in_as :georgie - patch group_url(@group), params: { - group: { - abbreviation: @group.abbreviation, - contact_email: @group.contact_email, - contact_name: @group.contact_name, - contact_phone: @group.contact_phone, - gdpr: @group.gdpr, - gdpr_email_verified: @group.gdpr_email_verified, - name: @group.name, - opening_hours: @group.opening_hours - } - } + patch group_url(@group), + params: { + group: { + abbreviation: @group.abbreviation, + contact_email: @group.contact_email, + contact_name: @group.contact_name, + contact_phone: @group.contact_phone, + gdpr: @group.gdpr, + gdpr_email_verified: @group.gdpr_email_verified, + name: @group.name, + opening_hours: @group.opening_hours + } + } assert_redirected_to group_url(@group) end test 'should destroy group' do sign_in_as :georgie group = groups(:unused) - assert_difference('Group.count', -1) do - delete group_url(group) - end + assert_difference('Group.count', -1) { delete group_url(group) } assert_redirected_to groups_url end diff --git a/test/controllers/initiative_statuses_controller_test.rb b/test/controllers/initiative_statuses_controller_test.rb index 709556f..7d53e6c 100644 --- a/test/controllers/initiative_statuses_controller_test.rb +++ b/test/controllers/initiative_statuses_controller_test.rb @@ -3,9 +3,7 @@ require 'test_helper' class InitiativeStatusesControllerTest < ActionDispatch::IntegrationTest - setup do - @initiative_status = initiative_statuses(:one) - end + setup { @initiative_status = initiative_statuses(:one) } test 'should get index' do sign_in_as :georgie @@ -22,9 +20,13 @@ class InitiativeStatusesControllerTest < ActionDispatch::IntegrationTest test 'should create initiative_status' do sign_in_as :georgie assert_difference('InitiativeStatus.count') do - post initiative_statuses_url, params: { - initiative_status: { description: @initiative_status.description, name: @initiative_status.name } - } + post initiative_statuses_url, + params: { + initiative_status: { + description: @initiative_status.description, + name: @initiative_status.name + } + } end assert_redirected_to initiative_statuses_path @@ -44,9 +46,13 @@ class InitiativeStatusesControllerTest < ActionDispatch::IntegrationTest test 'should update initiative_status' do sign_in_as :georgie - patch initiative_status_url(@initiative_status), params: { - initiative_status: { description: @initiative_status.description, name: @initiative_status.name } - } + patch initiative_status_url(@initiative_status), + params: { + initiative_status: { + description: @initiative_status.description, + name: @initiative_status.name + } + } assert_redirected_to initiative_status_url(@initiative_status) end diff --git a/test/controllers/tags_controller_test.rb b/test/controllers/tags_controller_test.rb index 9b11006..393f0af 100644 --- a/test/controllers/tags_controller_test.rb +++ b/test/controllers/tags_controller_test.rb @@ -3,9 +3,7 @@ require 'test_helper' class TagsControllerTest < ActionDispatch::IntegrationTest - setup do - @tag = tags(:one) - end + setup { @tag = tags(:one) } test 'should get index' do sign_in_as :georgie @@ -48,9 +46,7 @@ class TagsControllerTest < ActionDispatch::IntegrationTest test 'should destroy tag' do sign_in_as :georgie - assert_difference('Tag.count', -1) do - delete tag_url(@tag) - end + assert_difference('Tag.count', -1) { delete tag_url(@tag) } assert_redirected_to tags_url end diff --git a/test/fixtures/initiative_solutions.yml b/test/fixtures/initiative_solutions.yml new file mode 100644 index 0000000..050ab22 --- /dev/null +++ b/test/fixtures/initiative_solutions.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + solution: one + solution_class: one + initiative: one + +two: + solution: two + solution_class: two + initiative: two diff --git a/test/fixtures/sectors.yml b/test/fixtures/sectors.yml index 7d41224..cdb8859 100644 --- a/test/fixtures/sectors.yml +++ b/test/fixtures/sectors.yml @@ -1,7 +1,7 @@ # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html -one: - name: MyString +energy_sector: + name: Energy -two: - name: MyString +transport_sector: + name: Transport diff --git a/test/fixtures/solution_classes.yml b/test/fixtures/solution_classes.yml index 67841bf..68fd9ff 100644 --- a/test/fixtures/solution_classes.yml +++ b/test/fixtures/solution_classes.yml @@ -1,9 +1,9 @@ # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html -one: - name: MyString - theme: one +heat_pumps: + name: Heat pumps + theme: heating -two: - name: MyString - theme: two +apps: + name: Apps + theme: lift_share diff --git a/test/fixtures/solution_solution_classes.yml b/test/fixtures/solution_solution_classes.yml index 95726d1..47a8829 100644 --- a/test/fixtures/solution_solution_classes.yml +++ b/test/fixtures/solution_solution_classes.yml @@ -1,9 +1,9 @@ # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: - solution: one - solution_class: one + solution: ashp + solution_class: heat_pumps two: - solution: two - solution_class: two + solution: lift_share_app + solution_class: apps diff --git a/test/fixtures/solutions.yml b/test/fixtures/solutions.yml index 7d41224..1b9285b 100644 --- a/test/fixtures/solutions.yml +++ b/test/fixtures/solutions.yml @@ -1,7 +1,7 @@ # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html -one: - name: MyString +ashp: + name: ASHP -two: - name: MyString +lift_share_app: + name: Lift Share App diff --git a/test/fixtures/themes.yml b/test/fixtures/themes.yml index 1e2d663..065aa0c 100644 --- a/test/fixtures/themes.yml +++ b/test/fixtures/themes.yml @@ -1,9 +1,9 @@ # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html -one: - name: MyString - sector: one +heating: + name: Heating + sector: energy_sector -two: - name: MyString - sector: two +lift_share: + name: Lift Share + sector: transport_sector diff --git a/test/models/initiative_solution_test.rb b/test/models/initiative_solution_test.rb new file mode 100644 index 0000000..5422554 --- /dev/null +++ b/test/models/initiative_solution_test.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'test_helper' + +class InitiativeSolutionTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/solution_test.rb b/test/models/solution_test.rb index 353eb5c..25b7288 100644 --- a/test/models/solution_test.rb +++ b/test/models/solution_test.rb @@ -2,8 +2,73 @@ require 'test_helper' +# rubocop:disable all class SolutionTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end + test 'generates a flat list of solutions' do + solutions = Solution.all_flattened + assert_equal 2, solutions.size + expected_solution1 = { + solution: 'ASHP', class: 'Heat pumps', theme: 'Heating', sector: 'Energy' + } + expected_solution2 = { + solution: 'Lift Share App', + class: 'Apps', + theme: 'Lift Share', + sector: 'Transport' + } + assert_equal expected_solution1, + solutions[0].except(:solution_id, :class_id) + assert_equal expected_solution2, + solutions[1].except(:solution_id, :class_id) + end + + test 'generates a hierarchy of solutions' do + solution_hierarchy = Solution.hierarchy + expected = [ + { + name: 'Energy', + themes: [ + { + name: 'Heating', + classes: [ + { + name: 'Heat pumps', + solutions: [ + { + name: 'ASHP', + solution_id: ActiveRecord::FixtureSet.identify('ashp'), + solution_class_id: + ActiveRecord::FixtureSet.identify('heat_pumps') + } + ] + } + ] + } + ] + }, + { + name: 'Transport', + themes: [ + { + name: 'Lift Share', + classes: [ + { + name: 'Apps', + solutions: [ + { + name: 'Lift Share App', + solution_id: + ActiveRecord::FixtureSet.identify('lift_share_app'), + solution_class_id: ActiveRecord::FixtureSet.identify('apps') + } + ] + } + ] + } + ] + } + ] + assert_equal expected, solution_hierarchy + end end +# rubocop:enable all diff --git a/test/system/group_types_test.rb b/test/system/group_types_test.rb index 3d3408a..4d23181 100644 --- a/test/system/group_types_test.rb +++ b/test/system/group_types_test.rb @@ -3,9 +3,7 @@ require 'application_system_test_case' class GroupTypesTest < ApplicationSystemTestCase - setup do - @group_type = group_types(:one) - end + setup { @group_type = group_types(:one) } test 'visiting the index' do visit group_types_url @@ -36,9 +34,7 @@ class GroupTypesTest < ApplicationSystemTestCase test 'destroying a Group type' do visit group_types_url - page.accept_confirm do - click_on 'Destroy', match: :first - end + page.accept_confirm { click_on 'Destroy', match: :first } assert_text 'Group type was successfully destroyed' end diff --git a/test/system/group_websites_test.rb b/test/system/group_websites_test.rb index 46b177a..2d05f25 100644 --- a/test/system/group_websites_test.rb +++ b/test/system/group_websites_test.rb @@ -3,9 +3,7 @@ require 'application_system_test_case' class GroupWebsitesTest < ApplicationSystemTestCase - setup do - @group_website = group_websites(:one) - end + setup { @group_website = group_websites(:one) } test 'visiting the index' do visit group_websites_url @@ -38,9 +36,7 @@ class GroupWebsitesTest < ApplicationSystemTestCase test 'destroying a Group website' do visit group_websites_url - page.accept_confirm do - click_on 'Destroy', match: :first - end + page.accept_confirm { click_on 'Destroy', match: :first } assert_text 'Group website was successfully destroyed' end diff --git a/test/system/groups_test.rb b/test/system/groups_test.rb index ef6397f..7e10c6c 100644 --- a/test/system/groups_test.rb +++ b/test/system/groups_test.rb @@ -3,9 +3,7 @@ require 'application_system_test_case' class GroupsTest < ApplicationSystemTestCase - setup do - @group = groups(:one) - end + setup { @group = groups(:one) } test 'visiting the index' do visit groups_url @@ -50,9 +48,7 @@ class GroupsTest < ApplicationSystemTestCase test 'destroying a Group' do visit groups_url - page.accept_confirm do - click_on 'Destroy', match: :first - end + page.accept_confirm { click_on 'Destroy', match: :first } assert_text 'Group was successfully destroyed' end diff --git a/test/system/initiative_statuses_test.rb b/test/system/initiative_statuses_test.rb index 2154848..dcae23b 100644 --- a/test/system/initiative_statuses_test.rb +++ b/test/system/initiative_statuses_test.rb @@ -3,9 +3,7 @@ require 'application_system_test_case' class InitiativeStatusesTest < ApplicationSystemTestCase - setup do - @initiative_status = initiative_statuses(:one) - end + setup { @initiative_status = initiative_statuses(:one) } test 'visiting the index' do visit initiative_statuses_url @@ -38,9 +36,7 @@ class InitiativeStatusesTest < ApplicationSystemTestCase test 'destroying a Initiative status' do visit initiative_statuses_url - page.accept_confirm do - click_on 'Destroy', match: :first - end + page.accept_confirm { click_on 'Destroy', match: :first } assert_text 'Initiative status was successfully destroyed' end diff --git a/test/system/tags_test.rb b/test/system/tags_test.rb index 08a19f4..99a38ad 100644 --- a/test/system/tags_test.rb +++ b/test/system/tags_test.rb @@ -3,9 +3,7 @@ require 'application_system_test_case' class TagsTest < ApplicationSystemTestCase - setup do - @tag = tags(:one) - end + setup { @tag = tags(:one) } test 'visiting the index' do visit tags_url @@ -36,9 +34,7 @@ class TagsTest < ApplicationSystemTestCase test 'destroying a Tag' do visit tags_url - page.accept_confirm do - click_on 'Destroy', match: :first - end + page.accept_confirm { click_on 'Destroy', match: :first } assert_text 'Tag was successfully destroyed' end diff --git a/todo b/todo index 30619c6..d72810b 100644 --- a/todo +++ b/todo @@ -1,26 +1,6 @@ TODO -Add admin UI to approve initiatives - - -Create Solutions -> Sectors -solution -name:string - -solution_solution_classes -solution:references -solution_class:references - -solution_classes -name:string -theme:references - -themes -name:string -sector:references - -sector -name:string - +Add admin UI to remove/unapprove initiatives +edit solutions attached to saved initiative Lower priority @@ -41,10 +21,6 @@ initiative_partners initiative:references group:references -initiative_solutions -initiative:references -solution:references - initiative_tags initiative:references tag:references diff --git a/yarn.lock b/yarn.lock index 82b65f6..66b381c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -55,6 +55,14 @@ "@babel/helper-explode-assignable-expression" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-builder-react-jsx@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz#a1ac95a5d2b3e88ae5e54846bf462eeb81b318a4" + integrity sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw== + dependencies: + "@babel/types" "^7.3.0" + esutils "^2.0.0" + "@babel/helper-call-delegate@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz#87c1f8ca19ad552a736a7a27b1c1fcf8b1ff1f43" @@ -309,6 +317,20 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-jsx@7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0.tgz#034d5e2b4e14ccaea2e4c137af7e4afb39375ffd" + integrity sha512-PdmL2AoPsCLWxhIr3kG2+F9v4WH06Q3z+NoGVpQgnUNGcagXHq5sB3OXxkSahKq9TLdNMN/AJzFYSOo8UKDMHg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-jsx@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7" + integrity sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" @@ -509,6 +531,15 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-react-jsx@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz#f2cab99026631c767e2745a5368b331cfe8f5290" + integrity sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg== + dependencies: + "@babel/helper-builder-react-jsx" "^7.3.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/plugin-transform-regenerator@^7.4.5": version "7.4.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f" @@ -675,6 +706,15 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@babel/types@^7.3.0": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.3.tgz#3f07d96f854f98e2fbd45c64b0cb942d11e8ba09" + integrity sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + "@csstools/convert-colors@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" @@ -1317,6 +1357,27 @@ babel-plugin-macros@^2.5.0: cosmiconfig "^5.2.0" resolve "^1.10.0" +babel-plugin-transform-jsx-hyperdom-binding@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-jsx-hyperdom-binding/-/babel-plugin-transform-jsx-hyperdom-binding-2.0.0.tgz#9f1946a7658eac5737ead9a6a16b42cffcdae32a" + integrity sha512-KlSLJGc2X82I3E3OhShxpl5nCw5Gexem9uQNWwk6gzyhTu4SAHCYyINs7jwERTuAxte7XdH3NRAEuMp30U515A== + dependencies: + "@babel/plugin-syntax-jsx" "7.0.0" + babylon "6.17.4" + +babel-preset-hyperdom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/babel-preset-hyperdom/-/babel-preset-hyperdom-2.0.0.tgz#48deef698eddedf09ef3395b053ea55207c0d773" + integrity sha512-gTMusVs2Th70F+J2yiw2qDiHBkV5lFRGIjTGMszG2N1ECYk9hgohOe7R8OGiwWFbHUvjx1FHQ0hCV3tXZv0SHQ== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.3.0" + babel-plugin-transform-jsx-hyperdom-binding "^2.0.0" + +babylon@6.17.4: + version "6.17.4" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a" + integrity sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw== + bail@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.4.tgz#7181b66d508aa3055d3f6c13f0a0c720641dde9b" @@ -1453,6 +1514,11 @@ brorand@^1.0.1: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= +browser-split@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/browser-split/-/browser-split-0.0.1.tgz#7b097574f8e3ead606fb4664e64adfdda2981a93" + integrity sha1-ewl1dPjj6tYG+0Zk5krf3aKYGpM= + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -1682,6 +1748,11 @@ camelcase@^5.0.0, camelcase@^5.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +camelize@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" + integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= + caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" @@ -2622,6 +2693,11 @@ dom-serializer@0: domelementtype "^2.0.1" entities "^2.0.0" +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= + domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" @@ -2765,6 +2841,15 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +error@^4.3.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/error/-/error-4.4.0.tgz#bf69ff251fb4a279c19adccdaa6b61e90d9bf12a" + integrity sha1-v2n/JR+0onnBmtzNqmth6Q2b8So= + dependencies: + camelize "^1.0.0" + string-template "~0.2.0" + xtend "~4.0.0" + es-abstract@^1.12.0, es-abstract@^1.5.1: version "1.13.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" @@ -2786,7 +2871,7 @@ es-to-primitive@^1.2.0: is-date-object "^1.0.1" is-symbol "^1.0.2" -escape-html@~1.0.3: +escape-html@^1.0.1, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= @@ -2907,7 +2992,7 @@ estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -esutils@^2.0.2: +esutils@^2.0.0, esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== @@ -2917,6 +3002,13 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +ev-store@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/ev-store/-/ev-store-7.0.0.tgz#1ab0c7f82136505dd74b31d17701cb2be6d26558" + integrity sha1-GrDH+CE2UF3XSzHRdwHLK+bSZVg= + dependencies: + individual "^3.0.0" + eventemitter3@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" @@ -3547,6 +3639,14 @@ global-prefix@^3.0.0: kind-of "^6.0.2" which "^1.3.1" +global@^4.3.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + globals@^11.1.0, globals@^11.7.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -3881,6 +3981,15 @@ husky@^3.0.3: run-node "^1.0.0" slash "^3.0.0" +hyperdom@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/hyperdom/-/hyperdom-2.1.0.tgz#fc926e33141e23d6040efcbf80caf8833c4ad9c5" + integrity sha512-6WYkmJH1BmmvW0feAoRgz0sPU9dgOD5F041E28zXZZOB04HB9LF5ZgkXn2sOdcJNoZWObpMzReDq31eprcgQ/g== + dependencies: + vdom-parser "1.3.4" + vdom-to-html "2.3.1" + virtual-dom "2.1.1" + iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -4002,6 +4111,11 @@ indexes-of@^1.0.1: resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= +individual@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/individual/-/individual-3.0.0.tgz#e7ca4f85f8957b018734f285750dc22ec2f9862d" + integrity sha1-58pPhfiVewGHNPKFdQ3CLsL5hi0= + infer-owner@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" @@ -4326,6 +4440,11 @@ is-obj@^1.0.0, is-obj@^1.0.1: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= + is-observable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" @@ -4900,6 +5019,11 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + lru-cache@^4.0.1: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" @@ -5143,6 +5267,13 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + mini-css-extract-plugin@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.7.0.tgz#5ba8290fbb4179a43dd27cca444ba150bee743a0" @@ -5330,6 +5461,11 @@ neo-async@^2.5.0, neo-async@^2.6.1: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== +next-tick@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-0.2.2.tgz#75da4a927ee5887e39065880065b7336413b310d" + integrity sha1-ddpKkn7liH45BliABltzNkE7MQ0= + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -5839,6 +5975,13 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" +param-case@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-1.1.2.tgz#dcb091a43c259b9228f1c341e7b6a44ea0bf9743" + integrity sha1-3LCRpDwlm5Io8cNB57akTqC/l0M= + dependencies: + sentence-case "^1.1.2" + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -7612,6 +7755,13 @@ send@0.17.1: range-parser "~1.2.1" statuses "~1.5.0" +sentence-case@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-1.1.3.tgz#8034aafc2145772d3abe1509aa42c9e1042dc139" + integrity sha1-gDSq/CFFdy06vhUJqkLJ4QQtwTk= + dependencies: + lower-case "^1.1.1" + serialize-javascript@^1.4.0, serialize-javascript@^1.7.0: version "1.9.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.9.0.tgz#5b77019d7c3b85fe91b33ae424c53dcbfb6618bd" @@ -8001,6 +8151,11 @@ string-argv@^0.3.0: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== +string-template@~0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" + integrity sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0= + string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -8871,6 +9026,20 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= +vdom-parser@1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/vdom-parser/-/vdom-parser-1.3.4.tgz#cc4b44be2113791d34a954f5e3723e3b48bc8081" + integrity sha1-zEtEviETeR00qVT143I+O0i8gIE= + +vdom-to-html@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/vdom-to-html/-/vdom-to-html-2.3.1.tgz#14762673676d1b9cfb3f18d7eb566f527546519d" + integrity sha1-FHYmc2dtG5z7PxjX61ZvUnVGUZ0= + dependencies: + escape-html "^1.0.1" + param-case "^1.0.1" + xtend "^4.0.0" + vendors@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.3.tgz#a6467781abd366217c050f8202e7e50cc9eef8c0" @@ -8907,6 +9076,20 @@ vfile@^3.0.0: unist-util-stringify-position "^1.0.0" vfile-message "^1.0.0" +virtual-dom@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/virtual-dom/-/virtual-dom-2.1.1.tgz#80eda2d481b9ede0c049118cefcb4a05f21d1375" + integrity sha1-gO2i1IG57eDASRGM78tKBfIdE3U= + dependencies: + browser-split "0.0.1" + error "^4.3.0" + ev-store "^7.0.0" + global "^4.3.0" + is-object "^1.0.1" + next-tick "^0.2.2" + x-is-array "0.1.0" + x-is-string "0.1.0" + vm-browserify@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019" @@ -9146,12 +9329,17 @@ ws@^6.2.1: dependencies: async-limiter "~1.0.0" -x-is-string@^0.1.0: +x-is-array@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/x-is-array/-/x-is-array-0.1.0.tgz#de520171d47b3f416f5587d629b89d26b12dc29d" + integrity sha1-3lIBcdR7P0FvVYfWKbidJrEtwp0= + +x-is-string@0.1.0, x-is-string@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI= -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==