Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove cells in favour of fixed elements #1514

Merged
merged 9 commits into from
Jan 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/assets/javascripts/alchemy/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
//= require alchemy/alchemy.dragndrop
//= require alchemy/alchemy.element_editors
//= require alchemy/alchemy.elements_window
//= require alchemy/alchemy.fixed_elements
//= require alchemy/alchemy.growler
//= require alchemy/alchemy.gui
//= require alchemy/alchemy.hotkeys
Expand Down
24 changes: 0 additions & 24 deletions app/assets/javascripts/alchemy/alchemy.base.js.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -76,30 +76,6 @@ $.extend Alchemy,
dropdownAutoWidth: true
return

# Selects cell tab for given name.
# Creates it if it's not present yet.
selectOrCreateCellTab: (cell_name, label) ->
$cells = $('#cells')
$tab = $("#cell_#{cell_name}")
if $tab.length == 0
$("<li><a href=\"#cell_#{cell_name}\">#{label}</a></li>")
.appendTo('#cells .ui-tabs-nav')
$tab = $("<div id=\"cell_#{cell_name}\" class=\"sortable_cell\"/>")
$cells.append($tab)
$cells.tabs().tabs('refresh')
$cells.tabs().tabs('option', 'active', $('#cells > div').index($tab))
return

# Inits the cell tabs
buildTabbedCells: (label) ->
$cells = $('<div id="cells"/>')
$('#cell_for_other_elements').wrap($cells)
$('#cells').prepend("<ul><li><a href=\"#cell_for_other_elements\">#{label}</a></li></ul>")
.tabs 'paging',
follow: true
followOnSelect: true
return

# Logs exception to js console, if present.
debug: (e) ->
if window["console"]
Expand Down
5 changes: 1 addition & 4 deletions app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ window.Alchemy = {} if typeof (window.Alchemy) is "undefined"

$.extend Alchemy,

SortableElements: (page_id, form_token, selector = '#element_area .sortable_cell') ->
SortableElements: (page_id, form_token, selector = '#element_area .sortable-elements') ->
Alchemy.initializedSortableElements = false
$sortable_area = $(selector)

Expand Down Expand Up @@ -35,14 +35,11 @@ $.extend Alchemy,
Alchemy.initializedSortableElements = true
element_ids = $.map $this.children(), (child) ->
$(child).attr("data-element-id")
cell_id = $this.data("cell-id")
parent_element_id = ui.item.parent().closest("[data-element-id]").data('element-id')
params =
page_id: page_id
authenticity_token: encodeURIComponent(form_token)
element_ids: element_ids
if cell_id?
params['cell_id'] = cell_id
if parent_element_id?
params['parent_element_id'] = parent_element_id
$(event.target).css("cursor", "progress")
Expand Down
16 changes: 8 additions & 8 deletions app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ Alchemy.ElementEditors =
# Selects element
# Scrolls to element
# Unfold if folded
# Also chooses the right cell, if necessary.
# Also chooses the right fixed elements tab, if necessary.
# Can be triggered through custom event 'FocusElementEditor.Alchemy'
# Used by the elements on click events in the preview frame.
focusElement: ($element) ->
element_id = $element.attr('id').replace(/\D/g, "")
@selectCellForElement($element)
@selectTabForElement($element)
# If we have folded parents we need to unfold each of them
# and then finally scroll to or unfold ourself
$folded_parents = $element.parents('.element-editor.folded')
Expand All @@ -72,12 +72,12 @@ Alchemy.ElementEditors =
@scrollToOrUnfold(element_id)
return

# Select cell for given element
selectCellForElement: ($element) ->
$cells = $("#cells .sortable_cell")
if $cells.size() > 0
$cell = $element.closest(".sortable_cell")
$("#cells").tabs("option", "active", $cells.index($cell))
# Selects tab for given element
selectTabForElement: ($element) ->
$tabs = $("#fixed-elements .sortable-elements")
if $tabs.size() > 0
$tab = $element.closest(".sortable-elements")
$("#fixed-elements").tabs("option", "active", $tabs.index($tab))

# Marks an element as selected in the element window and scrolls to it.
#
Expand Down
38 changes: 38 additions & 0 deletions app/assets/javascripts/alchemy/alchemy.fixed_elements.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
window.Alchemy = Alchemy || {};

Alchemy.FixedElements = {
WRAPPER: '<div id="fixed-elements"></div>',
TABS: '<ul><li><a href="#main-content-elements">{{label}}</a></li></ul>',

// Builds fixed elements tabs
buildTabs: function(label) {
var $wrapper = $(this.WRAPPER),
$tabs = $(this.TABS.replace(/{{label}}/, label));

$('#main-content-elements').wrap($wrapper);
$('#fixed-elements').prepend($tabs).tabs('paging', {
follow: true,
followOnSelect: true
});
},

// Creates a fixed element tab.
createTab: function(element_id, label) {
var $fixed_elements = $('#fixed-elements'),
$tab;

$('> ul', $fixed_elements).append('<li><a href="#fixed-element-' + element_id + '">' + label + '</a></li>');
$tab = $('<div id="fixed-element-' + element_id + '" class="sortable-elements" />');
$fixed_elements.append($tab);
$fixed_elements.tabs().tabs('refresh');
$fixed_elements.tabs('option', 'active', $('#fixed-elements > div').index($tab));
},

removeTab: function(element_id) {
var $fixed_elements = $('#fixed-elements');

$fixed_elements.find('a[href="#fixed-element-' + element_id + '"]').parent().remove();
$fixed_elements.find('div#fixed-element-' + element_id).remove();
$fixed_elements.tabs().tabs('refresh');
}
};
36 changes: 29 additions & 7 deletions app/assets/stylesheets/alchemy/elements.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@
overflow-x: hidden;
overflow-y: auto;

.sortable_cell {
.sortable-elements {
min-height: 100px;
padding: 2*$default-padding $default-padding 2px;
}

textarea {
Expand All @@ -40,6 +39,11 @@
}
}

#main-content-elements,
.element-editor.is-fixed .nestable-elements {
padding: 2*$default-padding $default-padding 2px;
}

.element-title {
overflow: hidden;
white-space: nowrap;
Expand Down Expand Up @@ -111,6 +115,11 @@
margin-bottom: 2*$default-margin;
transition: box-shadow $transition-duration;

&.is-fixed {
border-width: 0;
border-radius: 0;
}

&.not-draggable {
opacity: 0.5;
}
Expand All @@ -123,7 +132,7 @@
}
}

&.selected {
&.selected:not(.is-fixed) {
border-color: #c3c3c3;
box-shadow: 0 2px 8px rgba(#9b9b9b, 0.75);
}
Expand Down Expand Up @@ -247,7 +256,6 @@
.element-toolbar {
padding: $default-padding 0;
height: $element-toolbar-height;
// background-color: #f0f0f0;

.element_tools {
float: left;
Expand Down Expand Up @@ -279,7 +287,7 @@
}
}

#cells {
#fixed-elements {
min-height: 100px;
}

Expand Down Expand Up @@ -669,7 +677,7 @@ textarea.has_tinymce {
top: -1px;
}

.nestable-elements {
.not-fixed .nestable-elements {
box-shadow: inset 0 4px 8px -2px darken($medium-gray, 15%);
background-color: $medium-gray;

Expand All @@ -684,7 +692,21 @@ textarea.has_tinymce {
}
}

.nested-elements {
.is-fixed {
&.with-contents {
> .element-footer {
border-top: 0;
border-bottom: 1px solid $medium-gray;
}
}

> .nestable-elements .add-nestable-element-button {
width: 100%;
text-align: center;
}
}

.not-fixed .nested-elements {
display: flex;
flex-wrap: wrap;

Expand Down
60 changes: 11 additions & 49 deletions app/controllers/alchemy/admin/elements_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@ class ElementsController < Alchemy::Admin::BaseController

def index
@page = Page.find(params[:page_id])
@cells = @page.cells
if @cells.blank?
@elements = @page.elements.not_trashed
else
@elements = @page.elements_grouped_by_cells
end
@elements = @page.elements
@fixed_elements = @page.fixed_elements
end

def list
Expand All @@ -39,21 +35,14 @@ def create
Element.transaction do
if @paste_from_clipboard = params[:paste_from_clipboard].present?
@element = paste_element_from_clipboard
@cell = @element.cell
else
@element = Element.new(create_element_params)
if @page.can_have_cells?
@cell = find_or_create_cell
@element.cell = @cell
end
@element.save
@element = Element.create(create_element_params)
end
if @page.definition['insert_elements_at'] == 'top'
@insert_at_top = true
@element.move_to_top
end
end
@cell_name = @cell.nil? ? "for_other_elements" : @cell.name
if @element.valid?
render :create
else
Expand Down Expand Up @@ -95,11 +84,10 @@ def order
@parent_element = Element.find_by(id: params[:parent_element_id])
Element.transaction do
params.fetch(:element_ids, []).each_with_index do |element_id, idx|
# Ensure to set page_id, cell_id and parent_element_id to the current page and
# cell because of trashed elements could still have old values
# Ensure to set page_id and parent_element_id to the current
# because of trashed elements could still have old values
Element.where(id: element_id).update_all(
page_id: params[:page_id],
cell_id: params[:cell_id],
parent_element_id: params[:parent_element_id],
position: idx + 1
)
Expand All @@ -120,24 +108,6 @@ def load_element
@element = Element.find(params[:id])
end

# Returns the cell for element name in params.
# Creates the cell if necessary.
def find_or_create_cell
if @paste_from_clipboard
element_with_cell_name = params[:paste_from_clipboard]
else
element_with_cell_name = params[:element][:name]
end
return nil if element_with_cell_name.blank?
return nil unless element_with_cell_name.include?('#')
cell_name = element_with_cell_name.split('#').last
cell_definition = Cell.definition_for(cell_name)
if cell_definition.blank?
raise CellDefinitionError, "Cell definition not found for #{cell_name}"
end
@page.cells.find_or_create_by(name: cell_definition['name'])
end

def element_from_clipboard
@element_from_clipboard ||= begin
@clipboard = get_clipboard('elements')
Expand All @@ -147,26 +117,18 @@ def element_from_clipboard

def paste_element_from_clipboard
@source_element = Element.find(element_from_clipboard['id'])
new_attributes = {
element = Element.copy(@source_element, {
parent_element_id: create_element_params[:parent_element_id],
page_id: @page.id
}
if @page.can_have_cells?
new_attributes = new_attributes.merge({cell_id: find_or_create_cell.try(:id)})
end
element = Element.copy(@source_element, new_attributes)
page_id: @page.id}
)
if element_from_clipboard['action'] == 'cut'
cut_element
@cut_element_id = @source_element.id
@clipboard.delete_if { |item| item['id'] == @source_element.id.to_s }
@source_element.destroy
end
element
end

def cut_element
@cutted_element_id = @source_element.id
@clipboard.delete_if { |item| item['id'] == @source_element.id.to_s }
@source_element.destroy
end

def contents_params
params.fetch(:contents, {}).permit!
end
Expand Down
13 changes: 7 additions & 6 deletions app/helpers/alchemy/admin/base_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -395,14 +395,15 @@ def alchemy_body_class

# (internal) Returns options for the clipboard select tag
def clipboard_select_tag_options(items)
if @page.persisted? && @page.can_have_cells?
grouped_options_for_select(grouped_elements_for_select(items, :id))
else
options = items.map do |item|
[item.respond_to?(:display_name_with_preview_text) ? item.display_name_with_preview_text : item.name, item.id]
options = items.map do |item|
if item.respond_to?(:display_name_with_preview_text)
name = item.display_name_with_preview_text
else
name = item.name
end
options_for_select(options)
[name, item.id]
end
options_for_select(options)
end

# Returns the regular expression used for external url validation in link dialog.
Expand Down
Loading