mirror of
https://github.com/redmine/redmine.git
synced 2025-11-06 05:16:12 +01:00
Makes the sidebar collapsible and stateful (#21808).
Patch inspired from user:jkraemer. git-svn-id: https://svn.redmine.org/redmine/trunk@23218 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -96,6 +96,14 @@
|
|||||||
<symbol viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" id="icon--checked">
|
<symbol viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" id="icon--checked">
|
||||||
<path d="M5 12l5 5l10 -10"/>
|
<path d="M5 12l5 5l10 -10"/>
|
||||||
</symbol>
|
</symbol>
|
||||||
|
<symbol viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" id="icon--chevrons-left">
|
||||||
|
<path d="M11 7l-5 5l5 5"/>
|
||||||
|
<path d="M17 7l-5 5l5 5"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" id="icon--chevrons-right">
|
||||||
|
<path d="M7 7l5 5l-5 5"/>
|
||||||
|
<path d="M13 7l5 5l-5 5"/>
|
||||||
|
</symbol>
|
||||||
<symbol viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" id="icon--clear-query">
|
<symbol viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" id="icon--clear-query">
|
||||||
<path d="M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14z"/>
|
<path d="M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14z"/>
|
||||||
<path d="M9 9l6 6m0 -6l-6 6"/>
|
<path d="M9 9l6 6m0 -6l-6 6"/>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@@ -1261,6 +1261,77 @@ function inlineAutoComplete(element) {
|
|||||||
tribute.attach(element);
|
tribute.attach(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// collapsible sidebar jQuery plugin
|
||||||
|
(function($) {
|
||||||
|
// main container this is applied to
|
||||||
|
var main;
|
||||||
|
// triggers show/hide
|
||||||
|
var button;
|
||||||
|
// the key to use in local storage
|
||||||
|
// this will later be expanded using the current controller and action to
|
||||||
|
// allow for different sidebar states for different pages
|
||||||
|
var localStorageKey = 'redmine-sidebar-state';
|
||||||
|
// true if local storage is available
|
||||||
|
var canUseLocalStorage = function(){
|
||||||
|
try {
|
||||||
|
if('localStorage' in window){
|
||||||
|
localStorage.setItem('redmine.test.storage', 'ok');
|
||||||
|
var item = localStorage.getItem('redmine.test.storage');
|
||||||
|
localStorage.removeItem('redmine.test.storage');
|
||||||
|
if(item === 'ok') return true;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
return false;
|
||||||
|
}();
|
||||||
|
// function to set current sidebar state
|
||||||
|
var setState = function(state){
|
||||||
|
if(canUseLocalStorage){
|
||||||
|
localStorage.setItem(localStorageKey, state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var applyState = function(){
|
||||||
|
if(main.hasClass('collapsedsidebar')){
|
||||||
|
updateSVGIcon(main[0], 'chevrons-left')
|
||||||
|
setState('hidden');
|
||||||
|
} else {
|
||||||
|
updateSVGIcon(main[0], 'chevrons-right')
|
||||||
|
setState('visible');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var setupToggleButton = function(){
|
||||||
|
button = $('#sidebar-switch-button');
|
||||||
|
button.click(function(e){
|
||||||
|
main.addClass("animate");
|
||||||
|
main.toggleClass('collapsedsidebar');
|
||||||
|
applyState();
|
||||||
|
e.preventDefault();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
applyState();
|
||||||
|
};
|
||||||
|
$.fn.collapsibleSidebar = function() {
|
||||||
|
main = this;
|
||||||
|
// determine previously stored sidebar state for this page
|
||||||
|
if(canUseLocalStorage) {
|
||||||
|
// determine current controller/action pair and use them as storage key
|
||||||
|
var bodyClass = $('body').attr('class');
|
||||||
|
if(bodyClass){
|
||||||
|
try {
|
||||||
|
localStorageKey += '-' + bodyClass.split(/\s+/).filter(function(s){
|
||||||
|
return s.match(/(action|controller)-.*/);
|
||||||
|
}).sort().join('-');
|
||||||
|
} catch(e) {
|
||||||
|
// in case of error (probably IE8), continue with the unmodified key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var storedState = localStorage.getItem(localStorageKey);
|
||||||
|
main.toggleClass('collapsedsidebar', storedState === 'hidden');
|
||||||
|
}
|
||||||
|
// draw the toggle button once the DOM is complete
|
||||||
|
$(document).ready(setupToggleButton);
|
||||||
|
};
|
||||||
|
}(jQuery));
|
||||||
|
|
||||||
$(document).ready(setupAjaxIndicator);
|
$(document).ready(setupAjaxIndicator);
|
||||||
$(document).ready(hideOnLoad);
|
$(document).ready(hideOnLoad);
|
||||||
$(document).ready(addFormObserversForDoubleSubmit);
|
$(document).ready(addFormObserversForDoubleSubmit);
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ pre, code {font-family: Consolas, Menlo, "Liberation Mono", Courier, monospace;}
|
|||||||
@media screen and (min-width: 1600px) and (max-width: 1919px) {#sidebar{width: 320px;}}
|
@media screen and (min-width: 1600px) and (max-width: 1919px) {#sidebar{width: 320px;}}
|
||||||
@media screen and (min-width: 1920px) and (max-width: 2559px) {#sidebar{width: 360px;}}
|
@media screen and (min-width: 1920px) and (max-width: 2559px) {#sidebar{width: 360px;}}
|
||||||
@media screen and (min-width: 2560px) {#sidebar{width: 380px;}}
|
@media screen and (min-width: 2560px) {#sidebar{width: 380px;}}
|
||||||
#sidebar h3{ font-size: 0.875rem; margin-top:14px; color: #555; }
|
#sidebar h3{ font-size: 0.875rem; color: #555; }
|
||||||
#sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
|
#sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
|
||||||
#sidebar .contextual { margin-right: 1em; }
|
#sidebar .contextual { margin-right: 1em; }
|
||||||
#sidebar ul, ul.flat {margin: 0; padding: 0;}
|
#sidebar ul, ul.flat {margin: 0; padding: 0;}
|
||||||
@@ -154,9 +154,32 @@ pre, code {font-family: Consolas, Menlo, "Liberation Mono", Courier, monospace;}
|
|||||||
#sidebar span.icon-warning {margin-left: 5px;}
|
#sidebar span.icon-warning {margin-left: 5px;}
|
||||||
#sidebar li input[type=checkbox] {height: 20px;}
|
#sidebar li input[type=checkbox] {height: 20px;}
|
||||||
|
|
||||||
|
#sidebar-switch-panel {
|
||||||
|
margin-left: -20px;
|
||||||
|
padding-right: 28px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar-switch-button {
|
||||||
|
display: block;
|
||||||
|
padding: 3px 0;
|
||||||
|
padding-right: 28px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
stroke: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#content { flex-grow: 1; background-color: #fff; margin: 0px; padding: 10px 16px 10px 16px; overflow-x: auto;}
|
#content { flex-grow: 1; background-color: #fff; margin: 0px; padding: 10px 16px 10px 16px; overflow-x: auto;}
|
||||||
|
|
||||||
#main.nosidebar #sidebar{ display: none; }
|
#main.nosidebar #sidebar { width: 0; padding-right: 0 }
|
||||||
|
#main.collapsedsidebar #sidebar { width: 0; padding-right: 0 }
|
||||||
|
#main.collapsedsidebar #sidebar-wrapper { display: none; }
|
||||||
|
|
||||||
#footer {clear: both; border-top: 1px solid #d0d7de; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
|
#footer {clear: both; border-top: 1px solid #d0d7de; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
|
||||||
|
|
||||||
|
|||||||
@@ -100,11 +100,21 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="main" class="<%= sidebar_content? ? '' : 'nosidebar' %>">
|
<div id="main" class="<%= sidebar_content? ? 'collapsiblesidebar' : 'nosidebar' %>">
|
||||||
|
<%= javascript_tag "$('#main.collapsiblesidebar').collapsibleSidebar();" if sidebar_content? %>
|
||||||
<div id="sidebar">
|
<div id="sidebar">
|
||||||
|
<% if sidebar_content? %>
|
||||||
|
<div id="sidebar-switch-panel" style="visibility: hidden;">
|
||||||
|
<a id="sidebar-switch-button" class="" href="#">
|
||||||
|
<%= sprite_icon("chevrons-right", size: 20) %></a>
|
||||||
|
</div>
|
||||||
|
<%= javascript_tag "$('#sidebar-switch-panel').css('visibility', 'visible');" %>
|
||||||
|
<% end %>
|
||||||
|
<div id=sidebar-wrapper %>
|
||||||
<%= yield :sidebar %>
|
<%= yield :sidebar %>
|
||||||
<%= view_layouts_base_sidebar_hook_response %>
|
<%= view_layouts_base_sidebar_hook_response %>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<%= render_flash_messages %>
|
<%= render_flash_messages %>
|
||||||
|
|||||||
@@ -191,4 +191,7 @@
|
|||||||
svg: file-type-zip
|
svg: file-type-zip
|
||||||
- name: application-gzip
|
- name: application-gzip
|
||||||
svg: file-zip
|
svg: file-zip
|
||||||
|
- name: chevrons-right
|
||||||
|
svg: chevrons-right
|
||||||
|
- name: chevrons-left
|
||||||
|
svg: chevrons-left
|
||||||
|
|||||||
Reference in New Issue
Block a user