-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add AdminActionListMixin to support action list burger menu.
- Loading branch information
1 parent
9275657
commit 17260f6
Showing
5 changed files
with
301 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
104 changes: 104 additions & 0 deletions
104
djangocms_version_locking/static/djangocms_version_locking/css/actions.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/*------------------------------------- | ||
General versioining action list styles | ||
---------------------------------------*/ | ||
|
||
/* ensure certain columns aren't too wide */ | ||
.field-get_title { | ||
min-width: 250px; | ||
word-break: break-word; | ||
white-space: normal !important; | ||
} | ||
|
||
.field-url { | ||
min-width: 100px; | ||
word-break: break-all; | ||
white-space: normal !important; | ||
} | ||
.cms-icon-menu { | ||
cursor: pointer; | ||
} | ||
|
||
/*------------------------------------- | ||
All action buttons | ||
---------------------------------------*/ | ||
.btn.cms-action-btn { | ||
position: relative; | ||
display: -webkit-inline-box; | ||
display: -ms-inline-flexbox; | ||
display: inline-flex; | ||
padding: 0 4px 0 7px !important; | ||
-webkit-box-align: center; | ||
-ms-flex-align: center; | ||
align-items: center; | ||
-webkit-box-pack: center; | ||
-ms-flex-pack: center; | ||
justify-content: center; | ||
height: 34px; | ||
margin-top: -12px !important; | ||
position: relative; | ||
height: 34px; | ||
bottom: -6px; | ||
-webkit-box-sizing: border-box; | ||
box-sizing: border-box; | ||
} | ||
|
||
/* disable clicking for inactive buttons */ | ||
.btn.cms-action-btn.inactive { | ||
pointer-events: none; | ||
background-color: #e1e1e1 !important; | ||
} | ||
|
||
.btn.cms-action-btn.inactive span { | ||
opacity: 0.5; | ||
} | ||
|
||
/*------------------------------------- | ||
This governs the drop-down behaviour | ||
extending the pagetree classes provided by CMS | ||
---------------------------------------*/ | ||
|
||
/* add shadow on burger menu trigger */ | ||
a.btn.cms-action-btn:hover, a.btn.cms-action-btn.open { | ||
box-shadow: inset 0 3px 5px rgba(0,0,0,.125); | ||
} | ||
|
||
/* style for each option row */ | ||
ul.cms-pagetree-dropdown-menu-inner li { | ||
border: 1px solid transparent; | ||
border-radius: 5px; | ||
padding: 2px 6px; | ||
} | ||
ul.cms-pagetree-dropdown-menu-inner li:hover { | ||
list-style-type: none; | ||
border: 1px solid #ccc; | ||
border-radius: 5px; | ||
background-color: #0bf; | ||
} | ||
|
||
/* align the option text with it's icon */ | ||
ul.cms-pagetree-dropdown-menu-inner li a span { | ||
line-height: 1rem; | ||
} | ||
|
||
/* disable any inactive option */ | ||
ul.cms-pagetree-dropdown-menu-inner li a.inactive { | ||
cursor: not-allowed; | ||
pointer-events: none; | ||
opacity: 0.3; | ||
filter: alpha(opacity=30); | ||
} | ||
|
||
/* set the size of the drop-down */ | ||
.cms-pagetree-dropdown-menu.open { | ||
display: block; | ||
width: 200px; | ||
} | ||
|
||
/* hide when closed */ | ||
.cms-pagetree-dropdown-menu.closed, .cms-icon-menu.closed .cms-pagetree-dropdown-menu { | ||
display: none; | ||
} | ||
|
||
.cms-pagetree-dropdown-menu:before { | ||
margin-top: 13px; | ||
} |
178 changes: 178 additions & 0 deletions
178
djangocms_version_locking/static/djangocms_version_locking/js/actions.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
"use strict"; | ||
|
||
(function ($) { | ||
if (!$) { | ||
return; | ||
} | ||
|
||
$(function () { | ||
var createBurgerMenu = function createBurgerMenu(row) { | ||
/* create burger menu anchor section */ | ||
var anchor = document.createElement('A'); | ||
var cssclass = document.createAttribute('class'); | ||
cssclass.value = 'btn cms-action-btn closed'; | ||
anchor.setAttributeNode(cssclass); | ||
// create burger menu title | ||
var title = document.createAttribute('title'); | ||
title.value = 'Actions'; | ||
anchor.setAttributeNode(title); | ||
// create burger menu icon | ||
var menu_icon = document.createElement('span'); | ||
menu_icon.className = "cms-icon cms-icon-menu"; | ||
anchor.appendChild(menu_icon); | ||
|
||
/* create options container */ | ||
var optionsContainer = document.createElement('DIV'); | ||
cssclass = document.createAttribute('class'); | ||
cssclass.value = 'cms-pagetree-dropdown-menu ' + // main selector for the menu | ||
'cms-pagetree-dropdown-menu-arrow-right-top'; // keeps the menu arrow in position | ||
|
||
optionsContainer.setAttributeNode(cssclass); | ||
var ul = document.createElement('UL'); | ||
cssclass = document.createAttribute('class'); | ||
cssclass.value = 'cms-pagetree-dropdown-menu-inner'; | ||
ul.setAttributeNode(cssclass); | ||
/* get the existing actions and move them into the options container */ | ||
|
||
var li; | ||
var text; | ||
var actions = $(row).children('.field-list_actions'); | ||
|
||
if (!actions.length) { | ||
/* skip any rows without actions to avoid errors */ | ||
return; | ||
} | ||
|
||
var actions_btn = $(actions[0]).children('.cms-action-btn'); | ||
if (actions_btn.length <=3) { | ||
return; | ||
} else { | ||
actions_btn.each(function (index, item) { | ||
/* exclude preview/view and edit buttons */ | ||
if (item.classList.contains('cms-action-preview') || | ||
item.classList.contains('cms-action-view') || | ||
item.classList.contains('cms-action-edit')) { | ||
return; | ||
} | ||
|
||
li = document.createElement('LI'); | ||
/* create an anchor from the item */ | ||
|
||
var li_anchor = document.createElement('A'); | ||
cssclass = document.createAttribute('class'); | ||
cssclass.value = 'cms-action-burger-options-anchor'; | ||
|
||
if ($(item).hasClass('cms-form-get-method')) { | ||
/* ensure the fake-form selector is propagated to the new anchor */ | ||
cssclass.value += ' cms-form-get-method'; | ||
} | ||
|
||
li_anchor.setAttributeNode(cssclass); | ||
var href = document.createAttribute('href'); | ||
href.value = $(item).attr('href'); | ||
li_anchor.setAttributeNode(href); | ||
/* move the an image element */ | ||
|
||
var existing_icon_span = $(item).children('span'); | ||
li_anchor.appendChild(existing_icon_span[0]); | ||
/* create the button text */ | ||
|
||
text = document.createTextNode(item.title); | ||
var span = document.createElement('SPAN'); | ||
span.appendChild(text); // construct the button | ||
|
||
li.appendChild(li_anchor); | ||
li_anchor.appendChild(span); | ||
ul.appendChild(li); | ||
/* destroy original replaced buttons */ | ||
|
||
actions[0].removeChild(item); | ||
}); | ||
} | ||
|
||
/* add the options to the drop-down */ | ||
optionsContainer.appendChild(ul); | ||
actions[0].appendChild(anchor); | ||
document.body.appendChild(optionsContainer); | ||
/* listen for burger menu clicks */ | ||
|
||
anchor.addEventListener('click', function (ev) { | ||
ev.stopPropagation(); | ||
toggleBurgerMenu(anchor, optionsContainer); | ||
}); | ||
/* close burger menu if clicking outside */ | ||
|
||
$(window).click(function () { | ||
closeBurgerMenu(); | ||
}); | ||
}; | ||
|
||
var toggleBurgerMenu = function toggleBurgerMenu(burgerMenuAnchor, optionsContainer) { | ||
var bm = $(burgerMenuAnchor); | ||
var op = $(optionsContainer); | ||
var closed = bm.hasClass('closed'); | ||
closeBurgerMenu(); | ||
|
||
if (closed) { | ||
bm.removeClass('closed'); | ||
bm.addClass('open'); | ||
op.removeClass('closed'); | ||
op.addClass('open'); | ||
} else { | ||
bm.addClass('closed'); | ||
bm.removeClass('open'); | ||
op.addClass('closed'); | ||
op.removeClass('open'); | ||
} | ||
|
||
var pos = bm.offset(); | ||
op.css('left', pos.left - 200); | ||
op.css('top', pos.top); | ||
}; | ||
|
||
var closeBurgerMenu = function closeBurgerMenu() { | ||
$('.cms-pagetree-dropdown-menu').removeClass('open'); | ||
$('.cms-pagetree-dropdown-menu').addClass('closed'); | ||
$('.cms-action-btn').removeClass('open'); | ||
$('.cms-action-btn').addClass('closed'); | ||
}; | ||
|
||
$('#result_list').find('tr').each(function (index, item) { | ||
createBurgerMenu(item); | ||
}); | ||
/* it is not possible to put a form inside a form, so | ||
actions have to create their own form on click */ | ||
|
||
var fakeForm = function fakeForm(e) { | ||
var action = $(e.currentTarget); | ||
var formMethod = action.attr('class').indexOf('cms-form-get-method') !== -1 ? 'GET' : 'POST'; | ||
if (formMethod == 'GET') return | ||
e.preventDefault(); | ||
|
||
var csrfToken = '<input type="hidden" name="csrfmiddlewaretoken" value="' + document.cookie.match(/csrftoken=([^;]*);?/)[1] + '">'; | ||
var fakeForm = $('<form style="display: none" action="' + action.attr('href') + '" method="' + formMethod + '">' + csrfToken + '</form>'); | ||
var keepSideFrame = action.attr('class').indexOf('js-keep-sideframe') !== -1; // always break out of the sideframe, cause it was never meant to open cms views inside it | ||
|
||
try { | ||
if (!keepSideFrame) { | ||
window.top.CMS.API.Sideframe.close(); | ||
} | ||
} catch (err) {} | ||
|
||
if (keepSideFrame) { | ||
var body = window.document.body; | ||
} else { | ||
var body = window.top.document.body; | ||
} | ||
|
||
fakeForm.appendTo(body).submit(); | ||
}; | ||
|
||
$('.js-action, .cms-js-publish-btn, .cms-js-edit-btn, .cms-action-burger-options-anchor').on('click', fakeForm); | ||
$('.js-close-sideframe').on('click', function () { | ||
try { | ||
window.top.CMS.API.Sideframe.close(); | ||
} catch (e) {} | ||
}); | ||
}); | ||
})(typeof django !== 'undefined' && django.jQuery || typeof CMS !== 'undefined' && CMS.$ || false); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from django import forms | ||
|
||
|
||
class AdminActionListMixin(metaclass=forms.MediaDefiningClass): | ||
"""AdminActionListMixin is a mixin for the Versioned Model class. It adds the ability to have | ||
action buttons and a burger menu in the admin's change list view. | ||
""" | ||
|
||
class Media: | ||
js = ( | ||
"admin/js/jquery.init.js", | ||
"djangocms_version_locking/js/actions.js", | ||
) | ||
css = {"all": ("djangocms_version_locking/css/actions.css",)} |