Class: Spree::Admin::Navigation

Inherits:
Object
  • Object
show all
Defined in:
app/models/spree/admin/navigation.rb,
app/models/spree/admin/navigation/item.rb,
app/models/spree/admin/navigation/builder.rb

Defined Under Namespace

Classes: Builder, Item

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(context) ⇒ Navigation

Returns a new instance of Navigation.



6
7
8
9
# File 'app/models/spree/admin/navigation.rb', line 6

def initialize(context)
  @context = context
  @items = {}
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



4
5
6
# File 'app/models/spree/admin/navigation.rb', line 4

def context
  @context
end

#itemsObject (readonly)

Returns the value of attribute items.



4
5
6
# File 'app/models/spree/admin/navigation.rb', line 4

def items
  @items
end

Instance Method Details

#add(key, **options, &block) ⇒ Object

Add a navigation item



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'app/models/spree/admin/navigation.rb', line 12

def add(key, **options, &block)
  key = key.to_sym
  item = Item.new(key, **options)

  @items[key] = item

  # If block provided, it's for children
  if block_given?
    builder = Builder.new(self, item)
    # Support both block styles: |nav| nav.add or just add
    if block.arity > 0
      # Block expects parameter: do |nav| nav.add ... end
      block.call(builder)
    else
      # Block uses implicit self: do add ... end
      builder.instance_eval(&block)
    end
  end

  sort_items!
  item
end

#build_treeObject

Build tree structure



137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'app/models/spree/admin/navigation.rb', line 137

def build_tree
  # First, clear all children
  @items.each_value { |item| item.children.clear }

  # Then rebuild the tree
  @items.each_value do |item|
    if item.parent_key && (parent = @items[item.parent_key])
      parent.add_child(item)
    end
  end

  root_items
end

#clearObject

Clear all items



152
153
154
# File 'app/models/spree/admin/navigation.rb', line 152

def clear
  @items.clear
end

#deep_cloneObject

Deep clone the registry



175
176
177
178
179
180
181
182
# File 'app/models/spree/admin/navigation.rb', line 175

def deep_clone
  cloned = self.class.new(context)
  @items.each do |key, item|
    cloned.items[key] = item.deep_clone
  end
  cloned.build_tree
  cloned
end

#exists?(key) ⇒ Boolean

Check if item exists

Returns:

  • (Boolean)


69
70
71
# File 'app/models/spree/admin/navigation.rb', line 69

def exists?(key)
  @items.key?(key.to_sym)
end

#find(key) ⇒ Object

Find a navigation item



64
65
66
# File 'app/models/spree/admin/navigation.rb', line 64

def find(key)
  @items[key.to_sym]
end

#insert_after(target_key, new_key, **options) ⇒ Object

Insert item after another item



83
84
85
86
87
88
89
# File 'app/models/spree/admin/navigation.rb', line 83

def insert_after(target_key, new_key, **options)
  target = find(target_key)
  return nil unless target

  new_position = target.position + 1
  add(new_key, **options.merge(position: new_position))
end

#insert_before(target_key, new_key, **options) ⇒ Object

Insert item before another item



74
75
76
77
78
79
80
# File 'app/models/spree/admin/navigation.rb', line 74

def insert_before(target_key, new_key, **options)
  target = find(target_key)
  return nil unless target

  new_position = target.position - 1
  add(new_key, **options.merge(position: new_position))
end

#move(key, position: nil, before: nil, after: nil) ⇒ Object

Move item to a new position



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'app/models/spree/admin/navigation.rb', line 92

def move(key, position: nil, before: nil, after: nil)
  item = find(key)
  return nil unless item

  if before
    target = find(before)
    item.position = target.position - 1 if target
  elsif after
    target = find(after)
    item.position = target.position + 1 if target
  elsif position == :first
    item.position = -999
  elsif position == :last
    item.position = 999
  elsif position.is_a?(Integer)
    item.position = position
  end

  sort_items!
  item
end

#registered_paths(context = nil) ⇒ Object

Get all registered paths (for settings_area? detection)



157
158
159
# File 'app/models/spree/admin/navigation.rb', line 157

def registered_paths(context = nil)
  @items.values.map { |item| item.resolve_url(context) }.compact
end

#remove(key) ⇒ Object

Remove a navigation item



36
37
38
39
40
41
42
43
44
45
46
# File 'app/models/spree/admin/navigation.rb', line 36

def remove(key)
  key = key.to_sym
  removed = @items.delete(key)

  # Also remove from any parent's children
  @items.each_value do |item|
    item.remove_child(key)
  end

  removed
end

#replace(key, **options, &block) ⇒ Object

Replace an item



115
116
117
118
# File 'app/models/spree/admin/navigation.rb', line 115

def replace(key, **options, &block)
  remove(key)
  add(key, **options, &block)
end

#root_itemsObject

Get all root items (items without a parent)



121
122
123
# File 'app/models/spree/admin/navigation.rb', line 121

def root_items
  @items.values.select { |item| item.parent_key.nil? }.sort_by { |item| [item.position, item.key.to_s] }
end

#section(key, label: nil, &block) ⇒ Object

Add a section



162
163
164
165
166
167
168
169
170
171
172
# File 'app/models/spree/admin/navigation.rb', line 162

def section(key, label: nil, &block)
  # Create a section header item
  section_item = add(key, section_label: label || key.to_s.humanize, position: @items.size * 100)

  if block_given?
    builder = Builder.new(self, section_item)
    builder.instance_eval(&block)
  end

  section_item
end

#update(key, **options) ⇒ Object

Update an existing navigation item



49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'app/models/spree/admin/navigation.rb', line 49

def update(key, **options)
  key = key.to_sym
  item = @items[key]

  return nil unless item

  options.each do |attr, value|
    item.send("#{attr}=", value) if item.respond_to?("#{attr}=")
  end

  sort_items!
  item
end

#visible_items(user = nil, parent_key = nil) ⇒ Object

Get all items that are visible to the user



126
127
128
129
130
131
132
133
134
# File 'app/models/spree/admin/navigation.rb', line 126

def visible_items(user = nil, parent_key = nil)
  items_to_filter = if parent_key
                      find(parent_key)&.children || []
                    else
                      root_items
                    end

  items_to_filter.select { |item| item.visible?(user) }
end