From 4e065e6279e6e65344a2c5c0e9de5cd9d7ecfa13 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Sat, 20 Aug 2016 14:22:44 -0400 Subject: add menu --- data/assets/js/admin/tabs/home.js | 143 +++++++++++++++++++++++++++++++++++++ src/guff/views/panel.cr | 72 +++++++++++++++++++ src/guff/views/panes/admin/home.cr | 71 +++++++++++++++--- 3 files changed, 277 insertions(+), 9 deletions(-) create mode 100644 data/assets/js/admin/tabs/home.js create mode 100644 src/guff/views/panel.cr diff --git a/data/assets/js/admin/tabs/home.js b/data/assets/js/admin/tabs/home.js new file mode 100644 index 0000000..b0f6eaf --- /dev/null +++ b/data/assets/js/admin/tabs/home.js @@ -0,0 +1,143 @@ +jQuery(function($) { + "use strict"; + + var TEMPLATES = new LuigiTemplate.Cache({ + panel: [DATA.panel_template], + }); + + function set_panel_editing(editing) { + // update panel headers + $('#home .home-editing').toggleClass('hidden', !editing); + $('#home .home-not-editing').toggleClass('hidden', editing); + + // flag panels as draggable + $('#home .panel').attr('draggable', editing); + } + + $('#admin-tab-home').on('show.bs.tab', function() { + // console.log('asdf'); + }); + + $('#home-edit-toggle').click(function() { + $(this).toggleClass('btn-default btn-primary'); + var editing = $(this).hasClass('btn-primary'), + panel = $(this).parents('.panel-heading'); + + // update buttons + panel.find('.btn-group.home-editing').toggleClass('hidden', !editing); + panel.find('.btn-group.home-not-editing').toggleClass('hidden', editing); + + set_panel_editing(editing); + + // stop event + return false; + }); + + $('#home-add').on('click', 'a', function() { + var data = $(this).data(); + + // hide dropdown + $('body').trigger('click'); + + // prepend new panel to first column + $('#home .home-col:first').prepend(TEMPLATES.run('panel', { + id: $.now(), + panel_class: 'panel-default', + config: '{}', + type: 'test', + name: data.name, + body: '

Sample body.

', + })); + + // flag panels as editable + set_panel_editing(true); + + // stop event + return false; + }); + + // cache column classes + var COL_CLASSES = $.map($('#home-cols a'), function(el) { + return $(el).data('col'); + }).join(' '); + + $('#home-cols').on('click', 'a', function() { + var data = $(this).data(), + ul = $(this).parents('.dropdown-menu'); + + // hide dropdown + $('body').trigger('click'); + + // update ui + ul.find('.active').removeClass('active'); + $(this).parent('li').addClass('active'); + ul.prev('a').find('span').text(data.name); + + var src_cols = $('#home .row .home-col'), + dst_num_cols = +data.id, + update_css = false; + + if (dst_num_cols > src_cols.length) { + for (var i = 0, l = dst_num_cols - src_cols.length; i < l; i++) + $('#home .row').append("
"); + + update_css = true; + } else if (dst_num_cols < src_cols.length) { + for (var i = 0, l = src_cols.length - dst_num_cols; i < l; i++) { + // append panels from deleted columns to last valid column + $.each($(src_cols[dst_num_cols + i]).find('.panel'), function(i, el) { + $(src_cols[dst_num_cols - 1]).append(el); + }); + + // remove old columns + $(src_cols.slice(dst_num_cols, src_cols.length)).remove(); + } + + update_css = true; + } else { + // do nothing, column count is fine + update_css = false; + } + + // update column classes, if necessary + if (update_css) + $('#home .row .home-col').removeClass(COL_CLASSES).addClass(data.col); + + // stop event + return false; + }); + + $('#home').on('dragstart', '.panel[draggable="true"]', function(ev) { + var oe = ev.originalEvent; + oe.dataTransfer.setData('text', oe.target.id); + + $('#home').addClass('dragging'); + }).on('dragend', '.panel[draggable="true"]', function(ev) { + $('#home').removeClass('dragging'); + }).on('dragover', '.home-col', function(ev) { + ev.preventDefault(); + }).on('drop', '.home-col', function(ev) { + ev.preventDefault(); + + var id = ev.originalEvent.dataTransfer.getData('text'); + $(this).append(document.getElementById(id)); + }).on('click', '.home-panel-edit a', function() { + var id = $(this).data('id'); + + // hide dropdown + $('body').trigger('click'); + + if (id == 'remove') { + if (confirm("Remove this panel?")) { + $($(this).parents('.panel')[0]).remove(); + } + } else if (id == 'edit') { + alert('TODO: ' + id + ' panel'); + } else { + // ignore unknown menu type + } + + // stop event + return false; + }); +}); diff --git a/src/guff/views/panel.cr b/src/guff/views/panel.cr new file mode 100644 index 0000000..025cc13 --- /dev/null +++ b/src/guff/views/panel.cr @@ -0,0 +1,72 @@ +module Guff::Views::Panel + TEMPLATE = Template.new(%{ +
+
+ + + + + + %{name|h} + +
+ +
+ %{body} +
+
+ }.strip) + + def self.make( + type : String, + id : String, + name : String, + body : String = "", + config : Hash(String, String) = {} of String => String, + panel_class : String = "panel-default", + ) + TEMPLATE.run({ + "type" => type, + "id" => id, + "name" => name, + "body" => body, + "config" => config.to_json, + "panel_class" => panel_class, + }) + end +end diff --git a/src/guff/views/panes/admin/home.cr b/src/guff/views/panes/admin/home.cr index 6010fd4..00bffed 100644 --- a/src/guff/views/panes/admin/home.cr +++ b/src/guff/views/panes/admin/home.cr @@ -28,20 +28,73 @@ class Guff::Views::Panes::Admin::Home < Guff::Views::Panes::Admin::Pane }.strip, + + "add-menu-category" => %{ + + }.strip, + + "divider" => %{ + + }.strip, }) - ADD_MENU_ITEMS = [{ - "id" => "test-1", - "name" => "Test 1", + ADD_MENU = [{ + "type" => "label", + "name" => "Content", + }, { + "id" => "pages", + "name" => "Pages", + }, { + "id" => "projects", + "name" => "Projects", + }, { + "id" => "quick-post", + "name" => "Quick Post", + }, { + "id" => "releases", + "name" => "Releases", + }, { + "type" => "divider", }, { - "id" => "test-2", - "name" => "Test 2", - }].map { |row| - TEMPLATES["add-menu-item"].run(row) - }.join + "type" => "label", + "name" => "Logs", + }, { + "id" => "activity", + "name" => "Activity", + }, { + "id" => "logins", + "name" => "Logins", + }, { + "id" => "traffic", + "name" => "Traffic", + }, { + "type" => "divider", + }, { + "type" => "label", + "name" => "Other", + }, { + "id" => "image-viewer", + "name" => "Image Viewer", + }, { + "id" => "tutorial", + "name" => "Tutorial", + }] private def add_menu - ADD_MENU_ITEMS + ADD_MENU.map { |row| + key = case row["type"]? + when "divider" + "divider" + when "label" + "add-menu-category" + else + "add-menu-item" + end + + TEMPLATES[key].run(row) + }.join end private def cols_menu -- cgit v1.2.3