From 3514d4d1da4f0772a80b1d8dee17b1933c21b1a8 Mon Sep 17 00:00:00 2001 From: Zee Spencer <50284+zspencer@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:51:23 -0800 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=A5=97=20`Marketplace`:=20Spec=20for?= =?UTF-8?q?=20`Product#tags`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - https://github.com/zinc-collective/convene/issues/2189 Lil' quick sketch through the workflow. Only interesting things of note here are I am using `scenario` syntax (which feels better to me, and was validated by @ExMember in antoher context yesterday.) I am also doing something "weird" where I overload the `visit` method to rely on our `Record#location` method to interject a `polymorphic_path` call; saving us the burden of including the `polymorphic_path` call on our own every time we use `visit`; but adding the burden of a layer of indirection. I also did this with `within`, because omg that awkward `"##{dom_id(model)"` drives me nuts every time I type it. It makes me want to scream. I can't stand it. --- .../marketplace/product_tags_system_spec.rb | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 spec/furniture/marketplace/product_tags_system_spec.rb diff --git a/spec/furniture/marketplace/product_tags_system_spec.rb b/spec/furniture/marketplace/product_tags_system_spec.rb new file mode 100644 index 000000000..1954ce1ab --- /dev/null +++ b/spec/furniture/marketplace/product_tags_system_spec.rb @@ -0,0 +1,46 @@ +require "rails_helper" + +describe "Product Tags", type: :system do + let(:space) { create(:space, :with_entrance, :with_members) } + let(:marketplace) { create(:marketplace, :ready_for_shopping, room: space.entrance) } + + before do + sign_in(space.members.first, space) + end + + scenario "Adding Tags to a Product" do # rubocop:disable RSpec/Capybara/FeatureMethods,RSpec/ExampleLength + muffins = create(:marketplace_product, marketplace:, name: "Mazin' Muffins", description: "Buttery corn muffins") + + visit(marketplace) + click_link("Tags") + + click_link("Add Tag") + + fill_in("Label", with: "🚫🌾 Gluten Free") + + click_button("Create") + + click_link("Products") + within(muffins) do + click_link("⚙️ Edit") + end + + visit(marketplace) + + within(muffins) do + expect(page).to have_content("🚫🌾 Gluten Free") + end + end + + def visit(object_or_path) + if object_or_path.respond_to?(:location) + super(polymorphic_path(object_or_path.location)) + else + super + end + end + + def within(model, *, **, &block) + page.within("##{dom_id(model)}", *, **, &block) + end +end From 2c17ad23f8d180dfef776a280d36a9d1f7b1dcb1 Mon Sep 17 00:00:00 2001 From: Zee Spencer <50284+zspencer@users.noreply.github.com> Date: Thu, 8 Feb 2024 08:38:23 -0800 Subject: [PATCH 2/3] =?UTF-8?q?=E2=9C=A8=20`Marketplace`:=20Adds=20`Produc?= =?UTF-8?q?t#tags`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Products can now be tagged with things like `Gluten Free` or `Vegan`, and will show up as such under Product listings --- app/furniture/marketplace/bazaar.rb | 1 + app/furniture/marketplace/breadcrumbs.rb | 10 ++++++ app/furniture/marketplace/locales/en.yml | 5 +++ .../marketplace/management_component.html.erb | 1 + app/furniture/marketplace/marketplace.rb | 2 ++ app/furniture/marketplace/policy.rb | 3 +- app/furniture/marketplace/product.rb | 3 ++ .../product/title_component.html.erb | 4 +++ app/furniture/marketplace/product_policy.rb | 2 +- app/furniture/marketplace/product_tag.rb | 8 +++++ .../marketplace/products/_form.html.erb | 2 ++ app/furniture/marketplace/routes.rb | 1 + app/furniture/marketplace/tag.rb | 12 +++++++ app/furniture/marketplace/tag_policy.rb | 32 +++++++++++++++++++ app/furniture/marketplace/tags/_form.html.erb | 6 ++++ app/furniture/marketplace/tags/index.html.erb | 20 ++++++++++++ app/furniture/marketplace/tags/new.html.erb | 2 ++ app/furniture/marketplace/tags_controller.rb | 31 ++++++++++++++++++ ...8025354_create_marketplace_product_tags.rb | 17 ++++++++++ db/schema.rb | 19 +++++++++++ .../marketplace/product_tags_system_spec.rb | 3 ++ 21 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 app/furniture/marketplace/product_tag.rb create mode 100644 app/furniture/marketplace/tag.rb create mode 100644 app/furniture/marketplace/tag_policy.rb create mode 100644 app/furniture/marketplace/tags/_form.html.erb create mode 100644 app/furniture/marketplace/tags/index.html.erb create mode 100644 app/furniture/marketplace/tags/new.html.erb create mode 100644 app/furniture/marketplace/tags_controller.rb create mode 100644 db/migrate/20240208025354_create_marketplace_product_tags.rb diff --git a/app/furniture/marketplace/bazaar.rb b/app/furniture/marketplace/bazaar.rb index 2f4362604..eee8c4763 100644 --- a/app/furniture/marketplace/bazaar.rb +++ b/app/furniture/marketplace/bazaar.rb @@ -4,6 +4,7 @@ class Marketplace class Bazaar < ::Space has_many :marketplaces, through: :rooms, source: :gizmos, inverse_of: :bazaar, class_name: "Marketplace" has_many :tax_rates, inverse_of: :bazaar, dependent: :destroy + has_many :tags, inverse_of: :bazaar, dependent: :destroy def space becomes(Space) diff --git a/app/furniture/marketplace/breadcrumbs.rb b/app/furniture/marketplace/breadcrumbs.rb index c26cb14ab..b09a1e3ff 100644 --- a/app/furniture/marketplace/breadcrumbs.rb +++ b/app/furniture/marketplace/breadcrumbs.rb @@ -104,6 +104,16 @@ link t("marketplace.stripe_accounts.show.link_to"), marketplace.location(child: :stripe_account) end +crumb :marketplace_tags do |marketplace| + parent :edit_marketplace, marketplace + link(t("marketplace.tags.index.link_to"), marketplace.location(child: :tags)) +end + +crumb :new_marketplace_tag do |tag| + parent :marketplace_tags, tag.marketplace + link t("marketplace.tags.new.link_to"), marketplace.location(:new, child: :tag) +end + crumb :marketplace_tax_rates do |marketplace| parent :edit_marketplace, marketplace link t("marketplace.tax_rates.index.link_to"), marketplace.location(child: :tax_rates) diff --git a/app/furniture/marketplace/locales/en.yml b/app/furniture/marketplace/locales/en.yml index a8c0aa18a..4da9047a0 100644 --- a/app/furniture/marketplace/locales/en.yml +++ b/app/furniture/marketplace/locales/en.yml @@ -136,3 +136,8 @@ en: payment_settings: index: link_to: "Payment Settings" + tags: + index: + link_to: "Tags" + new: + link_to: "Add Tag" diff --git a/app/furniture/marketplace/management_component.html.erb b/app/furniture/marketplace/management_component.html.erb index 5c7b32a85..76d802a9a 100644 --- a/app/furniture/marketplace/management_component.html.erb +++ b/app/furniture/marketplace/management_component.html.erb @@ -21,6 +21,7 @@ <%= link_to_child(:notification_methods, icon: :bell_alert) if policy(marketplace.notification_methods).index? %> <%= link_to_child(:flyer, icon: :qr_code) if policy(marketplace.flyer).show? %> <%= link_to_child(:vendor_representatives, icon: :building_storefront) if policy(marketplace.vendor_representatives).index? %> + <%= link_to_child(:tags, icon: :tag) if policy(marketplace.tags).index? %> <% end %> <% end %> diff --git a/app/furniture/marketplace/marketplace.rb b/app/furniture/marketplace/marketplace.rb index 0cd4a250a..1031296b2 100644 --- a/app/furniture/marketplace/marketplace.rb +++ b/app/furniture/marketplace/marketplace.rb @@ -9,6 +9,8 @@ class Marketplace < Furniture # @todo replace with through :bazaar has_many :tax_rates, inverse_of: :marketplace + has_many :tags, through: :bazaar + has_many :products, inverse_of: :marketplace, dependent: :destroy has_many :carts, inverse_of: :marketplace, dependent: :destroy has_many :orders, inverse_of: :marketplace diff --git a/app/furniture/marketplace/policy.rb b/app/furniture/marketplace/policy.rb index bbad7025c..f0912237f 100644 --- a/app/furniture/marketplace/policy.rb +++ b/app/furniture/marketplace/policy.rb @@ -2,7 +2,7 @@ class Marketplace class Policy < ApplicationPolicy def create? return true if current_person.operator? - return true if current_person.member_of?(marketplace.space) + return true if current_person.member_of?(space) return true if shopper&.person.blank? && !current_person.authenticated? @@ -23,6 +23,7 @@ def marketplace object.marketplace if object.respond_to?(:marketplace) end + delegate :space, to: :marketplace module SpecFactories def self.included(spec) diff --git a/app/furniture/marketplace/product.rb b/app/furniture/marketplace/product.rb index 93e2dd6d2..be06f3411 100644 --- a/app/furniture/marketplace/product.rb +++ b/app/furniture/marketplace/product.rb @@ -26,6 +26,9 @@ class Product < Record has_many :ordered_products, inverse_of: :product, dependent: :destroy has_many :orders, -> { checked_out }, through: :ordered_products, inverse_of: :products + has_many :product_tags, inverse_of: :product, dependent: :destroy + has_many :tags, through: :product_tags, inverse_of: :products + has_many :product_tax_rates, inverse_of: :product, dependent: :destroy has_many :tax_rates, through: :product_tax_rates, inverse_of: :products diff --git a/app/furniture/marketplace/product/title_component.html.erb b/app/furniture/marketplace/product/title_component.html.erb index 9f21e96af..b5626e5b9 100644 --- a/app/furniture/marketplace/product/title_component.html.erb +++ b/app/furniture/marketplace/product/title_component.html.erb @@ -2,3 +2,7 @@ <%- if servings.present? %>
Serves <%= servings %>
<%- end %> + +<%- if product.tags.present? %> +(<%= product.tags.pluck(:label).join(", ") %>)
+<%- end %> diff --git a/app/furniture/marketplace/product_policy.rb b/app/furniture/marketplace/product_policy.rb index ef63c0979..3b8d09636 100644 --- a/app/furniture/marketplace/product_policy.rb +++ b/app/furniture/marketplace/product_policy.rb @@ -4,7 +4,7 @@ class Marketplace class ProductPolicy < Policy alias_method :product, :object def permitted_attributes(_params = nil) - %i[name description price_cents price_currency price photo restore servings] + [tax_rate_ids: []] + %i[name description price_cents price_currency price photo restore servings] + [tag_ids: [], tax_rate_ids: []] end def update? diff --git a/app/furniture/marketplace/product_tag.rb b/app/furniture/marketplace/product_tag.rb new file mode 100644 index 000000000..368ddacd3 --- /dev/null +++ b/app/furniture/marketplace/product_tag.rb @@ -0,0 +1,8 @@ +class Marketplace + class ProductTag < Record + self.table_name = :marketplace_product_tags + + belongs_to :product, inverse_of: :product_tags + belongs_to :tag, inverse_of: :product_tags + end +end diff --git a/app/furniture/marketplace/products/_form.html.erb b/app/furniture/marketplace/products/_form.html.erb index c4e3f705b..4a38ab9db 100644 --- a/app/furniture/marketplace/products/_form.html.erb +++ b/app/furniture/marketplace/products/_form.html.erb @@ -5,6 +5,8 @@ <%= render "number_field", { attribute: :servings, form: f, min: 0, step: 1} %> <%= render "money_field", { attribute: :price, form: f, min: 0, step: 0.01} %> + <%= render "collection_check_boxes", { attribute: :tag_ids, collection: bazaar.tags, value_method: :id, + text_method: :label, form: f} %> <%= render "collection_check_boxes", { attribute: :tax_rate_ids, collection: bazaar.tax_rates, value_method: :id, text_method: :label, form: f} %> <%- if product.photo.present? %>