Class: Alchemy::Admin::ElementsController

Inherits:
BaseController
  • Object
show all
Includes:
Clipboard, PreviewTime
Defined in:
app/controllers/alchemy/admin/elements_controller.rb

Instance Method Summary collapse

Methods included from Clipboard

#clipboard_empty?

Methods inherited from BaseController

#leave

Instance Method Details

#collapse ⇒ Object

Collapses the element, all nested elements and persists the state in the db



137
138
139
140
141
142
143
144
145
146
147
148
# File 'app/controllers/alchemy/admin/elements_controller.rb', line 137

def collapse
  # We do not want to trigger the touch callback or any validations
  @element.update_columns(folded: true)
  # Collapse all nested elements (except compact ones which stay as-is)
  nested_element_ids = nested_element_ids_to_collapse(@element)
  Alchemy::Element.where(id: nested_element_ids).update_all(folded: true)

  render json: {
    nestedElementIds: nested_element_ids,
    title: Alchemy.t(@element.folded? ? :show_element_content : :hide_element_content)
  }
end

#create ⇒ Object

Creates a element as discribed in config/alchemy/elements.yml on page via AJAX.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'app/controllers/alchemy/admin/elements_controller.rb', line 34

def create
  @page_version = PageVersion.find(params[:element][:page_version_id])
  @page = @page_version.page
  Element.transaction do
    @paste_from_clipboard = params[:paste_from_clipboard].present?
    @element = if @paste_from_clipboard
      paste_element_from_clipboard
    else
      Element.new(create_element_params)
    end
    if @page.definition.insert_elements_at == "top"
      @insert_at_top = true
      @element.position = 1
    end
  end
  if @element.save
    render :create, status: 201
  else
    @parent_element = @element.parent_element
    @element.page_version = @page_version
    @elements = @page.available_elements_within_current_scope(@parent_element)
    render :new, status: 422
  end
end

#destroy ⇒ Object



90
91
92
93
94
95
96
# File 'app/controllers/alchemy/admin/elements_controller.rb', line 90

def destroy
  @element.destroy

  render json: {
    message: Alchemy.t("Successfully deleted element") % {element: @element.display_name}
  }.merge(pagePublicationData(@element.page))
end

#expand ⇒ Object

Expands the element, all parents and persists the state in the db



152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'app/controllers/alchemy/admin/elements_controller.rb', line 152

def expand
  # We do not want to trigger the touch callback or any validations
  @element.update_columns(folded: false)
  # We want to expand the upper most parent first in order to prevent
  # re-painting issues in the browser
  parent_element_ids = @element.folded_parent_element_ids.reverse
  Alchemy::Element.where(id: parent_element_ids).update_all(folded: false)

  render json: {
    parentElementIds: parent_element_ids,
    title: Alchemy.t(@element.folded? ? :show_element_content : :hide_element_content)
  }
end

#index ⇒ Object



15
16
17
18
19
20
21
22
23
24
# File 'app/controllers/alchemy/admin/elements_controller.rb', line 15

def index
  authorize! :edit_content, @page

  preloaded = Alchemy::ElementPreloader
    .new(page_version: @page_version)
    .call

  @elements = preloaded.reject(&:fixed?)
  @fixed_elements = preloaded.select(&:fixed?)
end

#new ⇒ Object



26
27
28
29
30
31
# File 'app/controllers/alchemy/admin/elements_controller.rb', line 26

def new
  @parent_element = Element.find_by(id: params[:parent_element_id])
  @elements = @page.available_elements_within_current_scope(@parent_element)
  @element = @page_version.elements.build
  clipboard_items
end

#order ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'app/controllers/alchemy/admin/elements_controller.rb', line 118

def order
  @element = Element.find(params[:element_id])

  # Update position
  @element.parent_element_id = params[:parent_element_id]
  @element.position = params[:position]

  # Skip validations when updating position, since new records may not yet meet all
  # validation requirements.
  @element.save(validate: false)

  render json: {
    message: Alchemy.t(:successfully_saved_element_position),
    preview_text: @element.preview_text
  }.merge(pagePublicationData(@element.page))
end

#publish ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'app/controllers/alchemy/admin/elements_controller.rb', line 98

def publish
  if schedule_element_params.present?
    @element.assign_attributes(schedule_element_params)
    @element.skip_ingredient_validations = true
    @element.save
    status = @element.valid? ? 200 : 422
  else
    @element.public = !@element.public?
    @element.save(validate: false)
    status = 200
  end

  respond_to do |format|
    format.turbo_stream do
      @page = @element.page
      render status:
    end
  end
end

#update ⇒ Object

Updates the element and all ingredients in the element.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'app/controllers/alchemy/admin/elements_controller.rb', line 61

def update
  if @element.update(element_params)
    render json: {
      notice: Alchemy.t(:element_saved),
      previewText: Rails::Html::SafeListSanitizer.new.sanitize(@element.preview_text),
      ingredientAnchors: @element.ingredients.filter_map do |ingredient|
        if ingredient.settings[:anchor]
          {
            ingredientId: ingredient.id,
            active: ingredient.dom_id.present?
          }
        end
      end
    }.merge(pagePublicationData(@element.page))
  else
    @warning = Alchemy.t("Validation failed")
    render json: {
      warning: @warning,
      errorMessage: Alchemy.t(:ingredient_validations_headline),
      ingredientsWithErrors: @element.ingredients_with_errors.map do |ingredient|
        {
          id: ingredient.id,
          errorMessage: ingredient.errors.messages[:value].to_sentence
        }
      end
    }, status: 422
  end
end