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 (
+
+ {this.results.map(solution => {
+ return (
+ - this.addSolution(solution)}
+ >
+ {solution.sector} > {solution.theme} > {solution.class} >{" "}
+ {solution.solution}
+
+ );
+ })}
+
+ );
+ }
+ 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 (
+
+ {this.taxonomy_hierarchy.map(sector => {
+ return (
+ - this.navigate({ sector })}>{sector.name}
+ );
+ })}
+
+ );
+ }
+
+ renderThemes() {
+ if (this.navigation.sector) {
+ return (
+
+ {this.navigation.sector.themes.map(theme => {
+ return (
+ - this.navigate({ theme })}>{theme.name}
+ );
+ })}
+
+ );
+ }
+ }
+
+ renderClasses() {
+ if (this.navigation.theme) {
+ return (
+
+ {this.navigation.theme.classes.map(solutionClass => {
+ return (
+ - this.navigate({ solutionClass })}>
+ {solutionClass.name}
+
+ );
+ })}
+
+ );
+ }
+ }
+
+ renderSolutions() {
+ if (this.navigation.solutionClass) {
+ return (
+
+ {this.navigation.solutionClass.solutions.map(solution => {
+ return (
+ -
+ {solution.name}{" "}
+
+ this.addSolution({
+ sector: this.navigation.sector.name,
+ theme: this.navigation.theme.name,
+ class: this.navigation.solutionClass.name,
+ solution: solution.name,
+ solution_id: solution.solution_id,
+ solution_class_id: solution.solution_class_id
+ })
+ }
+ >
+ [ add ]
+
+
+ );
+ })}
+
+ );
+ }
+ }
+
+ renderChosenSolutions() {
+ if (this.solutions.length === 0) {
+ return (
+
+ - Please select a solution
+
+ );
+ } else {
+ return (
+
+ {this.solutions.map((solution, index) => {
+ return (
+ -
+ {solution.sector} > {solution.theme} > {solution.class} >{" "}
+ {solution.solution}
+
+ this.removeSolution(solution)}
+ >
+ X
+
+
+
+
+ );
+ })}
+
+ );
+ }
+ }
+
+ 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==