Remove awesome nested set gem and dependencies [OFN-11636]

This commit is contained in:
wandji20
2024-08-07 19:35:24 +01:00
parent 193e17b625
commit a85cfab506
48 changed files with 206 additions and 908 deletions

View File

@@ -16,7 +16,6 @@ gem "image_processing"
gem 'activemerchant', '>= 1.78.0'
gem 'angular-rails-templates', '>= 0.3.0'
gem 'awesome_nested_set'
gem 'ransack', '~> 4.1.0'
gem 'responders'
gem 'webpacker', '~> 5'

View File

@@ -1,21 +0,0 @@
root = exports ? this
root.taxon_tree_menu = (obj, context) ->
base_url = Spree.url(Spree.routes.taxonomy_taxons)
admin_base_url = Spree.url(Spree.routes.admin_taxonomy_taxons)
edit_url = Spree.url(Spree.routes.admin_taxonomy_taxons + '/' + obj.attr("id") + "/edit");
create:
label: "<i class='icon-plus'></i> " + Spree.translations.add,
action: (obj) -> context.create(obj)
rename:
label: "<i class='icon-pencil'></i> " + Spree.translations.rename,
action: (obj) -> context.rename(obj)
remove:
label: "<i class='icon-trash'></i> " + Spree.translations.remove,
action: (obj) -> context.remove(obj)
edit:
separator_before: true,
label: "<i class='icon-edit'></i> " + Spree.translations.edit,
action: (obj) -> window.location = edit_url.toString()

View File

@@ -1,139 +0,0 @@
handle_ajax_error = (XMLHttpRequest, textStatus, errorThrown) ->
$.jstree.rollback(last_rollback)
$("#ajax_error").show().html("<strong>" + server_error + "</strong><br />" + taxonomy_tree_error)
handle_move = (e, data) ->
last_rollback = data.rlbk
position = data.rslt.cp
node = data.rslt.o
new_parent = data.rslt.np
url = new URL(Spree.routes.admin_taxonomy_taxons)
url.pathname = url.pathname + '/' + node.attr("id")
data = {
_method: "put",
"taxon[position]": position,
"taxon[parent_id]": if !isNaN(new_parent.attr("id")) then new_parent.attr("id") else undefined
}
$.ajax
type: "POST",
dataType: "json",
url: url.toString(),
data: data,
error: handle_ajax_error
true
handle_create = (e, data) ->
last_rollback = data.rlbk
node = data.rslt.obj
name = data.rslt.name
position = data.rslt.position
new_parent = data.rslt.parent
data = {
"taxon[name]": name,
"taxon[position]": position
"taxon[parent_id]": if !isNaN(new_parent.attr("id")) then new_parent.attr("id") else undefined
}
$.ajax
type: "POST",
dataType: "json",
url: base_url.toString(),
data: data,
error: handle_ajax_error,
success: (data,result) ->
node.attr('id', data.id)
handle_rename = (e, data) ->
last_rollback = data.rlbk
node = data.rslt.obj
name = data.rslt.new_name
# change the name inside the main input field as well if taxon is the root one
document.getElementById("taxonomy_name").value = name if node.parents("[id]").attr("id") == "taxonomy_tree"
url = new URL(base_url)
url.pathname = url.pathname + '/' + node.attr("id")
$.ajax
type: "POST",
dataType: "json",
url: url.toString(),
data: {_method: "put", "taxon[name]": name },
error: handle_ajax_error
handle_delete = (e, data) ->
last_rollback = data.rlbk
node = data.rslt.obj
delete_url = new URL(base_url)
delete_url.pathname = delete_url.pathname + '/' + node.attr("id")
if confirm(Spree.translations.are_you_sure_delete)
$.ajax
type: "POST",
dataType: "json",
url: delete_url.toString(),
data: {_method: "delete"},
error: handle_ajax_error
else
$.jstree.rollback(last_rollback)
last_rollback = null
root = exports ? this
root.setup_taxonomy_tree = (taxonomy_id) ->
if taxonomy_id != undefined
# this is defined within admin/taxonomies/edit
root.base_url = Spree.url(Spree.routes.taxonomy_taxons)
$.ajax
url: base_url.pathname.replace("/taxons", "/jstree"),
success: (taxonomy) ->
last_rollback = null
conf =
json_data:
data: taxonomy,
ajax:
url: (e) ->
base_url.pathname + '/' + e.attr('id') + '/jstree'
themes:
theme: "apple",
url: "/assets/jquery.jstree/themes/apple/style.css"
strings:
new_node: new_taxon,
loading: Spree.translations.loading + "..."
crrm:
move:
check_move: (m) ->
position = m.cp
node = m.o
new_parent = m.np
# no parent or cant drag and drop
if !new_parent || node.attr("rel") == "root"
return false
# can't drop before root
if new_parent.attr("id") == "taxonomy_tree" && position == 0
return false
true
contextmenu:
items: (obj) ->
taxon_tree_menu(obj, this)
plugins: ["themes", "json_data", "dnd", "crrm", "contextmenu"]
$("#taxonomy_tree").jstree(conf)
.bind("move_node.jstree", handle_move)
.bind("remove.jstree", handle_delete)
.bind("create.jstree", handle_create)
.bind("rename.jstree", handle_rename)
.bind "loaded.jstree", ->
$(this).jstree("core").toggle_node($('.jstree-icon').first())
$("#taxonomy_tree a").on "dblclick", (e) ->
$("#taxonomy_tree").jstree("rename", this)
# surpress form submit on enter/return
$(document).keypress (e) ->
if e.keyCode == 13
e.preventDefault()

View File

@@ -1,16 +0,0 @@
# frozen_string_literal: true
module Api
module V0
class TaxonomiesController < Api::V0::BaseController
respond_to :json
skip_authorization_check only: :jstree
def jstree
@taxonomy = Spree::Taxonomy.find(params[:id])
render json: @taxonomy.root, serializer: Api::TaxonJstreeSerializer
end
end
end
end

View File

@@ -5,12 +5,10 @@ module Api
class TaxonsController < Api::V0::BaseController
respond_to :json
skip_authorization_check only: [:index, :show, :jstree]
skip_authorization_check only: [:index, :show]
def index
@taxons = if taxonomy
taxonomy.root.children
elsif params[:ids]
@taxons = if params[:ids]
Spree::Taxon.where(id: raw_params[:ids].split(","))
else
Spree::Taxon.ransack(raw_params[:q]).result
@@ -18,23 +16,9 @@ module Api
render json: @taxons, each_serializer: Api::TaxonSerializer
end
def jstree
@taxon = taxon
render json: @taxon.children, each_serializer: Api::TaxonJstreeSerializer
end
def create
authorize! :create, Spree::Taxon
@taxon = Spree::Taxon.new(taxon_params)
@taxon.taxonomy_id = params[:taxonomy_id]
taxonomy = Spree::Taxonomy.find_by(id: params[:taxonomy_id])
if taxonomy.nil?
@taxon.errors.add(:taxonomy_id, I18n.t(:invalid_taxonomy_id, scope: 'spree.api'))
invalid_resource!(@taxon) && return
end
@taxon.parent_id = taxonomy.root.id unless params.dig(:taxon, :parent_id)
if @taxon.save
render json: @taxon, serializer: Api::TaxonSerializer, status: :created
@@ -60,20 +44,14 @@ module Api
private
def taxonomy
return if params[:taxonomy_id].blank?
@taxonomy ||= Spree::Taxonomy.find(params[:taxonomy_id])
end
def taxon
@taxon ||= taxonomy.taxons.find(params[:id])
@taxon = Spree::Taxon.find(params[:id])
end
def taxon_params
return if params[:taxon].blank?
params.require(:taxon).permit([:name, :parent_id, :position])
params.require(:taxon).permit([:name, :position])
end
end
end

View File

@@ -1,27 +0,0 @@
# frozen_string_literal: true
module Spree
module Admin
class TaxonomiesController < ::Admin::ResourceController
respond_to :json, only: [:get_children]
def get_children
@taxons = Taxon.find(params[:parent_id]).children
end
private
def location_after_save
if @taxonomy.created_at == @taxonomy.updated_at
spree.edit_admin_taxonomy_url(@taxonomy)
else
spree.admin_taxonomies_url
end
end
def permitted_resource_params
params.require(:taxonomy).permit(:name)
end
end
end
end

View File

@@ -2,122 +2,70 @@
module Spree
module Admin
class TaxonsController < Spree::Admin::BaseController
respond_to :html, :json, :js
class TaxonsController < ::Admin::ResourceController
before_action :set_taxon, except: %i[create index new]
def edit
@taxonomy = Taxonomy.find(params[:taxonomy_id])
@taxon = @taxonomy.taxons.find(params[:id])
@permalink_part = @taxon.permalink.split("/").last
def index
@taxons = Taxon.order(:name)
end
def new
@taxon = Taxon.new
end
def edit; end
def create
@taxonomy = Taxonomy.find(params[:taxonomy_id])
@taxon = @taxonomy.taxons.build(params[:taxon])
@taxon = Spree::Taxon.new(taxon_params)
if @taxon.save
respond_with(@taxon) do |format|
format.json { render json: @taxon.to_json }
end
flash[:success] = flash_message_for(@taxon, :successfully_created)
redirect_to edit_admin_taxon_path(@taxon.id)
else
flash[:error] = Spree.t('errors.messages.could_not_create_taxon')
respond_with(@taxon) do |format|
format.html do
if redirect_to @taxonomy
spree.edit_admin_taxonomy_url(@taxonomy)
else
spree.admin_taxonomies_url
end
end
end
render :new, status: :unprocessable_entity
end
end
def update
@taxonomy = Taxonomy.find(params[:taxonomy_id])
@taxon = @taxonomy.taxons.find(params[:id])
parent_id = params[:taxon][:parent_id]
new_position = params[:taxon][:position]
if parent_id || new_position # taxon is being moved
new_parent = parent_id.nil? ? @taxon.parent : Taxon.find(parent_id.to_i)
new_position = new_position.nil? ? -1 : new_position.to_i
# Bellow is a very complicated way of finding where in nested set we
# should actually move the taxon to achieve sane results,
# JS is giving us the desired position, which was awesome for previous setup,
# but now it's quite complicated to find where we should put it as we have
# to differenciate between moving to the same branch, up down and into
# first position.
new_siblings = new_parent.children
if new_position <= 0 && new_siblings.empty?
@taxon.move_to_child_of(new_parent)
elsif new_parent.id != @taxon.parent_id
if new_position.zero?
@taxon.move_to_left_of(new_siblings.first)
else
@taxon.move_to_right_of(new_siblings[new_position - 1])
end
elsif new_position < new_siblings.index(@taxon)
@taxon.move_to_left_of(new_siblings[new_position]) # we move up
else
@taxon.move_to_right_of(new_siblings[new_position - 1]) # we move down
end
# Reset legacy position, if any extensions still rely on it
new_parent.children.reload.each do |t|
t.update_columns(
position: t.position,
updated_at: Time.zone.now
)
end
if parent_id
@taxon.reload
@taxon.set_permalink
@taxon.save!
@update_children = true
end
end
if params.key? "permalink_part"
parent_permalink = @taxon.permalink.split("/")[0...-1].join("/")
parent_permalink += "/" if parent_permalink.present?
params[:taxon][:permalink] = parent_permalink + params[:permalink_part]
end
# check if we need to rename child taxons if parent name or permalink changes
if params[:taxon][:name] != @taxon.name || params[:taxon][:permalink] != @taxon.permalink
@update_children = true
end
if @taxon.update(taxon_params)
flash[:success] = flash_message_for(@taxon, :successfully_updated)
end
# rename child taxons
if @update_children
@taxon.descendants.each do |taxon|
taxon.reload
taxon.set_permalink
taxon.save!
end
end
respond_with(@taxon) do |format|
format.html { redirect_to spree.edit_admin_taxonomy_url(@taxonomy) }
format.json { render json: @taxon.to_json }
redirect_to edit_admin_taxon_path(@taxon.id)
else
render :edit, status: :unprocessable_entity
end
end
def destroy
@taxon = Taxon.find(params[:id])
@taxon.destroy
respond_with(@taxon) { |format| format.json { render json: '' } }
status = if @taxon.destroy
flash_message = t('.delete_taxon.success')
status = :ok
else
flash_message = t('.delete_taxon.error')
status = :unprocessable_entity
end
respond_to do |format|
format.html {
flash[:success] = flash_message if status == :ok
flash[:error] = flash_message if status == :unprocessable_entity
redirect_to admin_taxons_path
}
format.turbo_stream {
flash[:success] = flash_message if status == :ok
flash[:error] = flash_message if status == :unprocessable_entity
render :destroy_taxon, status:
}
end
end
private
def set_taxon
@taxon = Taxon.find(params[:id])
end
def taxon_params
params.require(:taxon).permit(
:name, :parent_id, :position, :icon, :description, :permalink, :taxonomy_id,
:name, :position, :icon, :description, :permalink,
:meta_description, :meta_keywords, :meta_title, :dfc_id
)
end

View File

@@ -1,11 +0,0 @@
# frozen_string_literal: true
module Spree
module Admin
module TaxonsHelper
def taxon_path(taxon)
taxon.ancestors.reverse.collect(&:name).join( " >> ")
end
end
end
end

View File

@@ -39,7 +39,6 @@ module Spree
can [:index, :read], StockLocation
can [:index, :read], StockMovement
can [:index, :read], Taxon
can [:index, :read], Taxonomy
can [:index, :read], Variant
can [:index, :read], Zone
end

View File

@@ -2,12 +2,6 @@
module Spree
class Taxon < ApplicationRecord
self.belongs_to_required_by_default = false
acts_as_nested_set dependent: :destroy
belongs_to :taxonomy, class_name: 'Spree::Taxonomy', touch: true
has_many :variants, class_name: "Spree::Variant", foreign_key: "primary_taxon_id",
inverse_of: :primary_taxon, dependent: :restrict_with_error
@@ -32,11 +26,7 @@ module Spree
end
def set_permalink
if parent.present?
self.permalink = [parent.permalink, permalink_end].join('/')
elsif permalink.blank?
self.permalink = UrlGenerator.to_url(name)
end
self.permalink = UrlGenerator.to_url(name)
end
# For #2759
@@ -44,13 +34,6 @@ module Spree
permalink
end
def pretty_name
ancestor_chain = ancestors.inject("") do |name, ancestor|
name + "#{ancestor.name} -> "
end
ancestor_chain + name.to_s
end
# Find all the taxons of supplied products for each enterprise, indexed by enterprise.
# Format: {enterprise_id => [taxon_id, ...]}
def self.supplied_taxons

View File

@@ -1,27 +0,0 @@
# frozen_string_literal: true
module Spree
class Taxonomy < ApplicationRecord
validates :name, presence: true
has_many :taxons, dependent: :nullify
has_one :root, -> { where parent_id: nil }, class_name: "Spree::Taxon", dependent: :destroy
after_save :set_name
default_scope -> { order("#{table_name}.position") }
private
def set_name
if root
root.update_columns(
name:,
updated_at: Time.zone.now
)
else
self.root = Taxon.create!(taxonomy_id: id, name:)
end
end
end
end

View File

@@ -3,7 +3,7 @@
module Api
module Admin
class TaxonSerializer < ActiveModel::Serializer
attributes :id, :name, :pretty_name
attributes :id, :name
end
end
end

View File

@@ -4,5 +4,5 @@ class Api::TaxonSerializer < ActiveModel::Serializer
cached
delegate :cache_key, to: :object
attributes :id, :name, :permalink, :pretty_name, :position, :parent_id, :taxonomy_id
attributes :id, :name, :permalink, :position
end

View File

@@ -15,7 +15,7 @@
- if DefaultCountry.id
= configurations_sidebar_menu_item Spree.t(:states), admin_country_states_path(DefaultCountry.id)
= configurations_sidebar_menu_item Spree.t(:payment_methods), admin_payment_methods_path
= configurations_sidebar_menu_item Spree.t(:taxonomies), admin_taxonomies_path
= configurations_sidebar_menu_item Spree.t(:taxons), admin_taxons_path
= configurations_sidebar_menu_item Spree.t(:shipping_methods), admin_shipping_methods_path
= configurations_sidebar_menu_item Spree.t(:shipping_categories), admin_shipping_categories_path
= configurations_sidebar_menu_item t(:enterprise_fees), main_app.admin_enterprise_fees_path

View File

@@ -3,7 +3,7 @@
= tab :order_cycles, url: main_app.admin_order_cycles_path, icon: 'icon-refresh'
= tab :orders, :subscriptions, :customer_details, :adjustments, :payments, :return_authorizations, url: admin_orders_path, icon: 'icon-shopping-cart'
= tab :reports, url: main_app.admin_reports_path, icon: 'icon-file'
= tab :general_settings, :terms_of_service_files, :mail_methods, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxonomies, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, :connected_app_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path
= tab :general_settings, :terms_of_service_files, :mail_methods, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxons, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, :connected_app_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path
= tab :enterprises, :enterprise_relationships, :vouchers, :oidc_settings, url: main_app.admin_enterprises_path
= tab :customers, url: main_app.admin_customers_path
= tab :enterprise_groups, url: main_app.admin_enterprise_groups_path, label: 'groups'

View File

@@ -1,7 +0,0 @@
.field.align-center
= f.field_container :name do
= f.label :name, t("spree.name")
%span.required *
%br/
= error_message_on :taxonomy, :name
= text_field :taxonomy, :name

View File

@@ -1,13 +0,0 @@
<% content_for :head do %>
<%= javascript_tag "var taxonomy_id = #{@taxonomy.id};
var loading = '#{escape_javascript t("spree.loading")}';
var new_taxon = '#{escape_javascript t("spree.new_taxon")}';
var server_error = '#{escape_javascript t("spree.server_error")}';
var taxonomy_tree_error = '#{escape_javascript t("spree.taxonomy_tree_error")}';
$(document).ready(function(){
setup_taxonomy_tree(taxonomy_id);
});
"
%>
<% end %>

View File

@@ -1,19 +0,0 @@
%table#listing_taxonomies.index.sortable{"data-sortable-link" => update_positions_admin_taxonomies_url}
%colgroup
%col{style: "width: 85%"}/
%col{style: "width: 15%"}/
%thead
%tr
%th= t("spree.name")
%th.actions
%tbody
- @taxonomies.each do |taxonomy|
- tr_class = cycle('odd', 'even')
- tr_id = spree_dom_id(taxonomy)
%tr{class: tr_class, id: tr_id}
%td
%span.handle
= taxonomy.name
%td.actions
= link_to_edit taxonomy.id, no_text: true
= link_to_delete taxonomy, no_text: true

View File

@@ -1,7 +0,0 @@
- if taxon.children.length != 0
%ul
- taxon.children.each do |child|
%li{id: "#{child.id}", rel: "taxon"}
%a{href: "#"}= child.name
- if child.children.length > 0
= render partial: 'taxon', locals: { taxon: child }

View File

@@ -1,27 +0,0 @@
= render partial: 'spree/admin/shared/configuration_menu'
= render partial: 'js_head'
- content_for :page_title do
= t("spree.taxonomy_edit")
- content_for :page_actions do
%li
= button_link_to t("spree.back_to_taxonomies_list"), spree.admin_taxonomies_path, icon: 'icon-arrow-left'
#ajax_error.errorExplanation{style: "display:none;"}
= form_for [:admin, @taxonomy] do |f|
%fieldset.no-border-top
= render partial: 'form', locals: { f: f }
%div
= label_tag nil, t("spree.tree")
%br/
:javascript
Spree.routes.taxonomy_taxons = "#{main_app.api_v0_taxonomy_taxons_url(@taxonomy)}";
Spree.routes.admin_taxonomy_taxons = "#{spree.admin_taxonomy_taxons_url(@taxonomy)}";
#taxonomy_tree.tree
.info= t("spree.taxonomy_tree_instruction")
%br/
.filter-actions.actions
= button t('spree.actions.update'), 'icon-refresh'
= button_link_to t('spree.actions.cancel'), admin_taxonomies_path, icon: 'icon-remove'

View File

@@ -1,11 +0,0 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.taxonomies")
- content_for :page_actions do
%li
= button_link_to t("spree.new_taxonomy"), spree.new_admin_taxonomy_url, icon: 'icon-plus', id: 'admin_new_taxonomy_link'
#list-taxonomies
= render partial: 'list'

View File

@@ -1,15 +0,0 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.new_taxonomy")
- content_for :page_actions do
%li
= button_link_to t("spree.back_to_taxonomies_list"), spree.admin_taxonomies_path, icon: 'icon-arrow-left'
= form_for [:admin, @taxonomy] do |f|
= render partial: 'form', locals: { f: f }
%fieldset.no-border-top
%br/
.filter-actions.actions
= button t("spree.create"), 'icon-ok'

View File

@@ -10,7 +10,8 @@
= f.label :permalink_part, t(".permalink")
%span.required *
%br/
= @taxon.permalink.split("/")[0...-1].join("/") + "/"
- if @taxon.permalink
= @taxon.permalink.split("/")[0...-1].join("/") + "/"
= text_field_tag :permalink_part, @permalink_part
= f.field_container :meta_title do
= f.label :meta_title, t(".meta_title")

View File

@@ -0,0 +1,4 @@
- unless flash[:error]
= turbo_stream.remove(spree_dom_id(@taxon))
= turbo_stream.append "flashes" do
= render(partial: 'admin/shared/flashes', locals: { flashes: flash })

View File

@@ -1,16 +1,16 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.taxonomy_edit")
= t(".title")
- content_for :page_actions do
%li
= button_link_to t("spree.back_to_taxonomies_list"), spree.admin_taxonomies_path, icon: 'icon-arrow-left'
= button_link_to t("spree.admin.taxons.back_to_list"), admin_taxons_path, icon: 'icon-arrow-left'
- # Because otherwise the form would attempt to use to_param of @taxon
- form_url = admin_taxonomy_taxon_path(@taxonomy.id, @taxon.id)
= form_for [:admin, @taxonomy, @taxon], method: :put, url: form_url, html: { multipart: true } do |f|
= form_with model: @taxon, url: admin_taxon_path(@taxon.id),
data: { turbo: true }, id: "edit-taxon-#{@taxon.id}",
method: :put, html: { multipart: true } do |f|
= render partial: 'form', locals: { f: f }
.form-buttons
= button t('spree.actions.update'), 'icon-refresh'
= button_link_to t('spree.actions.cancel'), edit_admin_taxonomy_url(@taxonomy), icon: "icon-remove"
= button_link_to t('spree.actions.cancel'), admin_taxons_url, icon: "icon-remove"

View File

@@ -0,0 +1,27 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t(".title")
- content_for :page_actions do
%li
= button_link_to t(".new_taxon"), spree.new_admin_taxon_url, icon: 'icon-plus', id: 'admin_new_taxon_link'
%table#listing_taxons.index
%colgroup
%col{style: "width: 85%"}/
%col{style: "width: 15%"}/
%thead
%tr
%th= t("spree.name")
%th.actions
%tbody
- @taxons.each do |taxon|
%tr{class: cycle('odd', 'even'), id: spree_dom_id(taxon)}
%td
= taxon.name
%td.actions
= link_to_edit taxon.id, no_text: true
= link_to '', admin_taxon_path(taxon.id), method: :delete,
class: "icon_link with-tip icon-trash no-text",
data: { turbo: true, turbo_method: :delete, turbo_confirm: t(:are_you_sure) }

View File

@@ -0,0 +1,14 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t(".title")
- content_for :page_actions do
%li
= button_link_to t("spree.admin.taxons.back_to_list"), spree.admin_taxons_path, icon: 'icon-arrow-left'
= form_with model: @taxon, url: admin_taxons_path, data: { turbo: true }, html: { multipart: true } do |f|
= render partial: 'form', locals: { f: f }
.form-buttons
= button t('actions.create'), 'icon-ok'
= button_link_to t('actions.cancel'), admin_taxons_url, icon: "icon-remove"

View File

@@ -34,7 +34,6 @@
@import "plugins/flatpickr-customization";
@import "plugins/powertip";
@import "plugins/jstree";
@import "plugins/select2";
@import "sections/orders";

View File

@@ -1,131 +0,0 @@
#taxonomy_tree {
> ul,
.jstree-icon {
background-image: none;
}
.jstree-icon {
@extend [class^="icon-"], :before;
}
.jstree-open > .jstree-icon {
@extend .icon-caret-down;
}
.jstree-closed > .jstree-icon {
@extend .icon-caret-right;
}
li {
background-image: none;
a {
background-color: very-light($color-3);
border: 1px solid $color-border;
color: $color-body-text;
font-weight: $font-weight-bold;
text-shadow: none;
width: 90%;
height: auto;
line-height: inherit;
padding: 5px 0 5px 10px;
margin-bottom: 10px;
.jstree-icon {
padding-left: 0px;
@extend .icon-move;
}
}
}
}
#vakata-dragged.jstree-apple .jstree-invalid,
#vakata-dragged.jstree-apple .jstree-ok,
#jstree-marker {
background-image: none !important;
background-color: transparent !important;
@extend [class^="icon-"], :before;
}
#vakata-dragged.jstree-apple .jstree-invalid {
@extend .icon-remove;
color: $color-5;
}
#vakata-dragged.jstree-apple .jstree-ok {
@extend .icon-ok;
color: $color-2;
}
#jstree-marker {
@extend .icon-caret-right;
color: $color-body-text !important;
width: 4px !important;
}
#jstree-marker-line {
@include border-radius($border-radius !important);
height: 0px !important;
margin-left: 5px !important;
margin-top: -2px !important;
border: none !important;
border-bottom: 1px solid $color-body-text !important;
background-color: very-light($color-3) !important;
-webkit-box-shadow: none !important;
-moz-box-shadow: none !important;
box-shadow: none !important;
}
#vakata-contextmenu {
background-color: $color-3 !important;
-moz-box-shadow: none !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
border: none !important;
@include border-radius($border-radius !important);
&:before {
content: "";
position: absolute;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid $color-3;
top: 0px;
margin-top: -10px;
left: 25px;
z-index: 1;
}
a {
color: $color-1 !important;
line-height: inherit !important;
padding: 5px 10px !important;
margin: 0 !important;
font-size: 90% !important;
&:hover {
@include border-radius($border-radius !important);
background-color: $color-2 !important;
border: none !important;
-moz-box-shadow: none !important;
-webkit-box-shadow: none !important;
line-height: inherit !important;
padding: 5px 10px !important;
margin: 0 !important;
}
}
li:first-child a:hover:before {
content: "";
position: absolute;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid $color-2;
top: 0px;
margin-top: -10px;
left: 25px;
z-index: 1;
}
li.vakata-separator {
display: none;
}
}

View File

@@ -39,7 +39,6 @@
@import "plugins/flatpickr-customization"; // admin_v3
@import "plugins/powertip"; // admin_v3
@import "../admin/plugins/jstree";
@import "sections/orders"; // admin_v3
@import "../admin/sections/products";

View File

@@ -3959,10 +3959,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using
delivery: "Signed, sealed, delivered"
start_date: "Start date"
successfully_removed: "Successfully Removed"
taxonomy_edit: "Taxonomy edit"
taxonomy_tree_error: "There was an error updating the taxonomy tree."
taxonomy_tree_instruction: "Right-click on an item to add, rename, remove or edit."
tree: "Tree"
updating: "Updating"
your_order_is_empty_add_product: "Your order is empty, please search for and add a product above"
add_product: "Add Product"
@@ -4086,10 +4082,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
new_state: "New State"
payment_methods: "Payment Methods"
taxonomies: "Taxonomies"
new_taxonomy: "New Taxonomy"
back_to_taxonomies_list: "Back to Taxonomies List"
taxons: "Product Categories"
shipping_methods: "Shipping Methods"
shipping_method: "Shipping Method"
@@ -4582,6 +4575,18 @@ See the %{link} to find out more about %{sitename}'s features and to start using
total: "Total"
billing_address_name: "Name"
taxons:
back_to_list: "Back to Product Categeory List"
index:
title: "Product Categories"
new_taxon: 'New product category'
new:
title: "New Product Category"
edit:
title: "Edit Product Category"
destroy:
delete_taxon:
success: "Successfully deleted the product category"
error: "Unable to delete the product category"
form:
name: Name
permalink: Permalink

View File

@@ -79,18 +79,7 @@ Openfoodnetwork::Application.routes.draw do
resources :states, :only => [:index, :show]
resources :taxons, :only => [:index]
resources :taxonomies do
member do
get :jstree
end
resources :taxons do
member do
get :jstree
end
end
end
resources :taxons, except: %i[show edit]
get '/reports/:report_type(/:report_subtype)', to: 'reports#show',
constraints: lambda { |_| OpenFoodNetwork::FeatureToggle.enabled?(:api_reports) }

View File

@@ -142,15 +142,7 @@ Spree::Core::Engine.routes.draw do
end
resources :states
resources :taxonomies do
collection do
post :update_positions
end
member do
get :get_children
end
resources :taxons
end
resources :taxons, except: :show
resources :tax_rates
resource :tax_settings

View File

@@ -0,0 +1,14 @@
class DropSpreeTaxonomiesTable < ActiveRecord::Migration[7.0]
def change
# Remove columns
remove_column :spree_taxons, :lft
remove_column :spree_taxons, :rgt
# Remove references
remove_reference :spree_taxons, :parent, index: true, foriegn_key: true
remove_reference :spree_taxons, :taxonomy, index: true, foriegn_key: true
# Drop table
drop_table :spree_taxonomies
end
end

View File

@@ -878,31 +878,18 @@ ActiveRecord::Schema[7.0].define(version: 2024_08_10_150912) do
t.datetime "deleted_at", precision: nil
end
create_table "spree_taxonomies", id: :serial, force: :cascade do |t|
t.string "name", limit: 255, null: false
t.datetime "created_at", precision: nil, null: false
t.datetime "updated_at", precision: nil, null: false
t.integer "position", default: 0
end
create_table "spree_taxons", id: :serial, force: :cascade do |t|
t.integer "parent_id"
t.integer "position", default: 0
t.string "name", limit: 255, null: false
t.string "permalink", limit: 255
t.integer "taxonomy_id"
t.datetime "created_at", precision: nil, null: false
t.datetime "updated_at", precision: nil, null: false
t.integer "lft"
t.integer "rgt"
t.text "description"
t.string "meta_title", limit: 255
t.string "meta_description", limit: 255
t.string "meta_keywords", limit: 255
t.string "dfc_id"
t.index ["parent_id"], name: "index_taxons_on_parent_id"
t.index ["permalink"], name: "index_taxons_on_permalink"
t.index ["taxonomy_id"], name: "index_taxons_on_taxonomy_id"
end
create_table "spree_tokenized_permissions", id: :serial, force: :cascade do |t|
@@ -1220,8 +1207,6 @@ ActiveRecord::Schema[7.0].define(version: 2024_08_10_150912) do
add_foreign_key "spree_stock_movements", "spree_stock_items", column: "stock_item_id"
add_foreign_key "spree_tax_rates", "spree_tax_categories", column: "tax_category_id", name: "spree_tax_rates_tax_category_id_fk"
add_foreign_key "spree_tax_rates", "spree_zones", column: "zone_id", name: "spree_tax_rates_zone_id_fk"
add_foreign_key "spree_taxons", "spree_taxonomies", column: "taxonomy_id", name: "spree_taxons_taxonomy_id_fk"
add_foreign_key "spree_taxons", "spree_taxons", column: "parent_id", name: "spree_taxons_parent_id_fk"
add_foreign_key "spree_users", "spree_addresses", column: "bill_address_id", name: "spree_users_bill_address_id_fk"
add_foreign_key "spree_users", "spree_addresses", column: "ship_address_id", name: "spree_users_ship_address_id_fk"
add_foreign_key "spree_variants", "enterprises", column: "supplier_id"

View File

@@ -2,7 +2,6 @@
require 'active_merchant'
require 'acts_as_list'
require 'awesome_nested_set'
require 'cancan'
require 'pagy'
require 'mail'
@@ -35,7 +34,3 @@ require 'spree/core/permalinks'
require 'spree/core/token_resource'
require 'spree/core/product_duplicator'
require 'spree/core/gateway_error'
ActiveRecord::Base.class_eval do
include CollectiveIdea::Acts::NestedSet
end

View File

@@ -8,23 +8,20 @@ module SampleData
def create_samples
log "Creating taxonomies:"
taxonomy = Spree::Taxonomy.find_or_create_by!(name: 'Products')
taxons = ['Vegetables', 'Fruit', 'Oils', 'Preserves and Sauces', 'Dairy', 'Fungi']
taxons.each do |taxon_name|
create_taxon(taxonomy, taxon_name)
create_taxon(taxon_name)
end
end
private
def create_taxon(taxonomy, taxon_name)
def create_taxon(taxon_name)
return if Spree::Taxon.where(name: taxon_name).exists?
log "- #{taxon_name}"
Spree::Taxon.create!(
name: taxon_name,
parent_id: taxonomy.root.id,
taxonomy_id: taxonomy.id
name: taxon_name
)
end
end

View File

@@ -1,34 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
module Api
RSpec.describe V0::TaxonomiesController do
render_views
let(:taxonomy) { create(:taxonomy) }
let(:taxon) { create(:taxon, name: "Ruby", taxonomy:) }
let(:taxon2) { create(:taxon, name: "Rails", taxonomy:) }
let(:attributes) { [:id, :name] }
before do
allow(controller).to receive(:spree_current_user) { current_api_user }
taxon2.children << create(:taxon, name: "3.2.2", taxonomy:)
taxon.children << taxon2
taxonomy.root.children << taxon
end
context "as a normal user" do
let(:current_api_user) { build(:user) }
it "gets the jstree-friendly version of a taxonomy" do
api_get :jstree, id: taxonomy.id
expect(json_response["data"]).to eq(taxonomy.root.name)
expect(json_response["attr"]).to eq("id" => taxonomy.root.id, "name" => taxonomy.root.name)
expect(json_response["state"]).to eq("closed")
end
end
end
end

View File

@@ -5,30 +5,19 @@ require 'spec_helper'
RSpec.describe Api::V0::TaxonsController do
render_views
let(:taxonomy) { create(:taxonomy) }
let(:taxon) { create(:taxon, name: "Ruby", taxonomy:) }
let(:taxon2) { create(:taxon, name: "Rails", taxonomy:) }
let(:attributes) {
["id", "name", "pretty_name", "permalink", "position", "parent_id", "taxonomy_id"]
let!(:taxon) { create(:taxon, name: "Ruby") }
let!(:taxon2) { create(:taxon, name: "Rails") }
let!(:attributes) {
["id", "name", "permalink", "position"]
}
before do
allow(controller).to receive(:spree_current_user) { current_api_user }
taxon2.children << create(:taxon, name: "3.2.2", taxonomy:)
taxon.children << taxon2
taxonomy.root.children << taxon
end
context "as a normal user" do
let(:current_api_user) { build(:user) }
it "gets all taxons for a taxonomy" do
api_get :index, taxonomy_id: taxonomy.id
expect(json_response.first['name']).to eq taxon.name
end
it "gets all taxons" do
api_get :index
@@ -43,31 +32,21 @@ RSpec.describe Api::V0::TaxonsController do
expect(json_response.first['name']).to eq "Ruby"
end
it "gets all taxons in JSTree form" do
api_get :jstree, taxonomy_id: taxonomy.id, id: taxon.id
response = json_response.first
expect(response["data"]).to eq(taxon2.name)
expect(response["attr"]).to eq("name" => taxon2.name, "id" => taxon2.id)
expect(response["state"]).to eq("closed")
end
it "cannot create a new taxon if not an admin" do
api_post :create, taxonomy_id: taxonomy.id, taxon: { name: "Location" }
api_post :create, taxon: { name: "Location" }
assert_unauthorized!
end
it "cannot update a taxon" do
api_put :update, taxonomy_id: taxonomy.id,
id: taxon.id,
api_put :update, id: taxon.id,
taxon: { name: "I hacked your store!" }
assert_unauthorized!
end
it "cannot delete a taxon" do
api_delete :destroy, taxonomy_id: taxonomy.id, id: taxon.id
api_delete :destroy, id: taxon.id
assert_unauthorized!
end
@@ -77,42 +56,25 @@ RSpec.describe Api::V0::TaxonsController do
let(:current_api_user) { build(:admin_user) }
it "can create" do
api_post :create, taxonomy_id: taxonomy.id, taxon: { name: "Colors" }
api_post :create, taxon: { name: "Colors" }
expect(attributes.all? { |a| json_response.include? a }).to be true
expect(response.status).to eq(201)
expect(taxonomy.reload.root.children.count).to eq 2
expect(Spree::Taxon.last.parent_id).to eq taxonomy.root.id
expect(Spree::Taxon.last.taxonomy_id).to eq taxonomy.id
end
it "cannot create a new taxon with invalid attributes" do
api_post :create, taxonomy_id: taxonomy.id, taxon: {}
api_post :create, taxon: {}
expect(response.status).to eq(422)
expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.")
errors = json_response["errors"]
expect(taxonomy.reload.root.children.count).to eq 1
end
it "cannot create a new taxon with invalid taxonomy_id" do
api_post :create, taxonomy_id: 1000, taxon: { name: "Colors" }
expect(response.status).to eq(422)
expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.")
errors = json_response["errors"]
expect(errors["taxonomy_id"]).not_to be_nil
expect(errors["taxonomy_id"].first).to eq "Invalid taxonomy id."
expect(taxonomy.reload.root.children.count).to eq 1
expect(Spree::Taxon.last).to eq taxon2
expect(errors['name']).to eq ["can't be blank"]
end
it "can destroy" do
api_delete :destroy, taxonomy_id: taxonomy.id, id: taxon2.id
api_delete :destroy, id: taxon2.id
expect(response.status).to eq(204)
end

View File

@@ -5,28 +5,68 @@ require 'spec_helper'
RSpec.describe Spree::Admin::TaxonsController do
render_views
let(:taxonomy) { create(:taxonomy) }
let(:taxon) { create(:taxon, name: "Ruby", taxonomy:) }
let(:taxon2) { create(:taxon, name: "Rails", taxonomy:) }
let!(:taxon) { create(:taxon, name: "Ruby") }
let!(:taxon2) { create(:taxon, name: "Rails") }
let(:valid_attributes) { attributes_for(:taxon) }
before do
allow(controller).to receive(:spree_current_user) { current_api_user }
taxonomy.root.children << taxon
taxonomy.root.children << taxon2
end
context "as an admin" do
describe 'admin user' do
let(:current_api_user) { build(:admin_user) }
it "can reorder taxons" do
spree_post :update,
taxonomy_id: taxonomy.id,
id: taxon2.id,
taxon: { parent_id: taxonomy.root.id, position: 0 }
it "can view all taxons" do
spree_get :index
expect(taxon2.reload.lft).to eq 2
expect(Spree::Taxonomy.find(taxonomy.id).root.children.first).to eq(taxon2)
expect(response).to have_http_status :ok
end
it "open taxon edit form" do
spree_get :edit, { id: taxon.id }
expect(response).to have_http_status :ok
end
it "open taxon edit form" do
spree_get :new
expect(response).to have_http_status :ok
end
context "create" do
it "persist data with valid attributes" do
spree_post :create, valid_attributes
expect(Spree::Taxon.last.name).to eq valid_attributes[:name]
expect(response).to have_http_status :found
end
it "returns error with invalid attributes" do
spree_post :create, { name: '' }
expect(Spree::Taxon.count).to eq 2
expect(response).to have_http_status :unprocessable_entity
end
end
context "update" do
let!(:new_taxon) { create(:taxon, valid_attributes) }
it "persist data with valid attributes" do
spree_post :update, id: new_taxon.id,
taxon: valid_attributes.merge({ name: 'Taxon name updated' })
expect(new_taxon.reload.name).to eq 'Taxon name updated'
expect(response).to have_http_status :found
end
it "retruns error with invalid attributes" do
spree_post :update, id: new_taxon.id,
taxon: { **valid_attributes, name: '' }
expect(new_taxon.reload.name).to eq valid_attributes[:name]
expect(response).to have_http_status :unprocessable_entity
end
end
end
end

View File

@@ -3,7 +3,5 @@
FactoryBot.define do
factory :taxon, class: Spree::Taxon do
name { 'Ruby on Rails' }
taxonomy
parent_id { nil }
end
end

View File

@@ -1,7 +0,0 @@
# frozen_string_literal: true
FactoryBot.define do
factory :taxonomy, class: Spree::Taxonomy do
name { 'Brand' }
end
end

View File

@@ -153,13 +153,6 @@ RSpec.describe Spree::Ability do
end
end
context 'for Taxonomy' do
let(:resource) { Spree::Taxonomy.new }
context 'requested by any user' do
it_should_behave_like 'read only'
end
end
context 'for User' do
context 'requested by same user' do
let(:resource) { user }

View File

@@ -63,41 +63,6 @@ module Spree
taxon.set_permalink
expect(taxon.permalink).to eq 'ni-hao'
end
context "with parent taxon" do
before do
allow(taxon).to receive_messages parent_id: 123
allow(taxon).to receive_messages parent: build_stubbed(:taxon, permalink: "brands")
end
it "should set permalink correctly when taxon has parent" do
taxon.set_permalink
expect(taxon.permalink).to eq "brands/ruby-on-rails"
end
it "should set permalink correctly with existing permalink present" do
taxon.permalink = "b/rubyonrails"
taxon.set_permalink
expect(taxon.permalink).to eq "brands/rubyonrails"
end
it "should support Chinese characters" do
taxon.name = ""
taxon.set_permalink
expect(taxon.permalink).to eq "brands/wo"
end
end
end
# Regression test for Spree #2620
context "creating a child node using first_or_create" do
let(:taxonomy) { create(:taxonomy) }
it "does not error out" do
expect {
taxonomy.root.children.where(name: "Some name").first_or_create
}.not_to raise_error
end
end
end
end

View File

@@ -1,19 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Spree::Taxonomy do
context "#destroy" do
before do
@taxonomy = create(:taxonomy)
@root_taxon = @taxonomy.root
@child_taxon = create(:taxon, taxonomy_id: @taxonomy.id, parent: @root_taxon)
end
it "should destroy all associated taxons" do
@taxonomy.destroy
expect{ Spree::Taxon.find(@root_taxon.id) }.to raise_error(ActiveRecord::RecordNotFound)
expect{ Spree::Taxon.find(@child_taxon.id) }.to raise_error(ActiveRecord::RecordNotFound)
end
end
end

View File

@@ -13,7 +13,9 @@ RSpec.describe ProductScopeQuery do
before { current_api_user.enterprise_roles.create(enterprise: supplier2) }
describe '#bulk_products' do
let!(:product3) { create(:product, supplier_id: supplier2.id) }
let!(:product3) {
create(:product, supplier_id: supplier2.id, primary_taxon_id: create(:taxon).id)
}
it "returns a list of products" do
expect(ProductScopeQuery.new(current_api_user, {}).bulk_products)

View File

@@ -1,59 +0,0 @@
# frozen_string_literal: true
require 'system_helper'
RSpec.describe "Taxonomies" do
include AuthenticationHelper
include WebHelper
before(:each) do
login_as_admin
visit spree.edit_admin_general_settings_path
end
context "show" do
it "should display existing taxonomies" do
create(:taxonomy, name: 'Brand')
create(:taxonomy, name: 'Categories')
click_link "Taxonomies"
within("table.index tbody") do
expect(page).to have_content("Brand")
expect(page).to have_content("Categories")
end
end
end
context "create" do
before(:each) do
click_link "Taxonomies"
click_link "admin_new_taxonomy_link"
end
it "should allow an admin to create a new taxonomy" do
expect(page).to have_content("New Taxonomy")
fill_in "taxonomy_name", with: "sports"
click_button "Create"
expect(page).to have_content("successfully created!")
end
it "should display validation errors" do
fill_in "taxonomy_name", with: ""
click_button "Create"
expect(page).to have_content("can't be blank")
end
end
context "edit" do
it "should allow an admin to update an existing taxonomy" do
create(:taxonomy)
click_link "Taxonomies"
within_row(1) { find(".icon-edit").click }
fill_in "taxonomy_name", with: "sports 99"
sleep 1
click_button "Update"
expect(page).to have_current_path spree.admin_taxonomies_path
expect(page).to have_content("successfully updated!")
expect(page).to have_content("sports 99")
end
end
end

View File

@@ -130,7 +130,7 @@ RSpec.describe "As a consumer I want to view products" do
add_variant_to_order_cycle(exchange1, variant2)
end
context "product taxonomies" do
context "product taxons" do
before do
distributor.preferred_shopfront_product_sorting_method = "by_category"
distributor.preferred_shopfront_taxon_order = taxon.id.to_s