aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/assets/js/admin/tabs/home.js143
-rw-r--r--src/guff/views/panel.cr72
-rw-r--r--src/guff/views/panes/admin/home.cr71
3 files changed, 277 insertions, 9 deletions
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: '<p>Sample body.</p>',
+ }));
+
+ // 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("<div class='home-col'></div>");
+
+ 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(%{
+ <div
+ id='home-panel-%{id|h}'
+ class='panel %{panel_class|h}'
+ data-type='%{type|h}'
+ data-config='%{config|h}'
+ >
+ <div class='panel-heading dropup'>
+ <a
+ href='#'
+ class='btn btn-default btn-xs home-editing hidden'
+ title='Edit panel.'
+ data-toggle='dropdown'
+ >
+ <i class='fa fa-cog'></i>
+ <i class='fa fa-caret-down'></i>
+ </a>
+
+ <ul class='dropdown-menu home-panel-edit'>
+ <li role='presentation'>
+ <a
+ href='#'
+ title='Configure this panel.'
+ data-id='edit'
+ >
+ <i class='fa fa-list-alt'></i>
+ Configure...
+ </a>
+ </li>
+
+ <li role='presentation'>
+ <a
+ href='#'
+ title='Remove this panel.'
+ data-id='remove'
+ >
+ <i class='fa fa-trash'></i>
+ Remove
+ </a>
+ </li>
+ </ul>
+
+ <b>
+ %{name|h}
+ </b>
+ </div><!-- panel-heading -->
+
+ <div class='panel-body'>
+ %{body}
+ </div><!-- panel-body -->
+ </div>
+ }.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
</a>
</li>
}.strip,
+
+ "add-menu-category" => %{
+ <li class='dropdown-header'>
+ %{name|h}
+ </li>
+ }.strip,
+
+ "divider" => %{
+ <li class='divider' role='separator'></li>
+ }.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