-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
267 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# EditorConfig is awesome: https://EditorConfig.org | ||
|
||
# top-most EditorConfig file | ||
root = true | ||
|
||
# Unix-style newlines with a newline ending every file | ||
[*] | ||
end_of_line = lf | ||
insert_final_newline = true | ||
trim_trailing_whitespace = true | ||
indent_style = space | ||
indent_size = 2 | ||
charset = utf-8 | ||
|
||
[*.{md,markdown}] | ||
trim_trailing_whitespace = false | ||
indent_size = 4 |
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,6 @@ | ||
{ | ||
"cSpell.words": [ | ||
"jstb", | ||
"Jstoolbar" | ||
] | ||
} |
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 |
---|---|---|
@@ -1 +1,34 @@ | ||
# redmine_jstoolbar_slider | ||
# Redmine jsToolBar Slider | ||
|
||
This is a plugin for Redmine. | ||
This plugin adds two buttons to the right edge of the jsToolBar that allow | ||
sliding the toolbar buttons when the toolbar is overflowing. | ||
|
||
## Demo | ||
|
||
![](/doc/images/jsToolbar_slider_demo.gif) | ||
|
||
## Compatibility | ||
|
||
Only Redmine v5.0.5 has been tested. | ||
Other versions are untested. | ||
|
||
## Installation | ||
|
||
### When using git | ||
|
||
1. Change the current directory to the Redmine plugin directory. | ||
``` | ||
cd YOUR_REDMINE_DIRECTORY/plugins | ||
``` | ||
2. Clone this repository. | ||
``` | ||
git clone https://github.com/sk-ys/redmine_jstoolbar_slider.git | ||
``` | ||
3. Restart Redmine. | ||
|
||
### When not using git | ||
|
||
1. Download zip file from the [release page](https://github.com/sk-ys/redmine_jstoolbar_slider/releases) or the [latest main repository](https://github.com/sk-ys/redmine_jstoolbar_slider/archive/refs/heads/main.zip). | ||
2. Extract the ZIP file to your Redmine plugin directory. The name of the unzipped directory must be `redmine_jstoolbar_slider`. | ||
3. Restart Redmine. |
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 @@ | ||
<% content_for :header_tags do %> | ||
<script> | ||
var JstoolbarSlider = { | ||
config: { | ||
resources: { | ||
labelUndo: "<%= l(:jstoolbar_slider_label_undo) %>", | ||
labelRedo: "<%= l(:jstoolbar_slider_label_redo) %>", | ||
} | ||
} | ||
} | ||
</script> | ||
<%= javascript_include_tag "jstoolbar_slider", plugin: "redmine_jstoolbar_slider" %> | ||
<%= stylesheet_link_tag "jstoolbar_slider", plugin: "redmine_jstoolbar_slider" %> | ||
<% end %> |
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,141 @@ | ||
(() => { | ||
if (typeof jsToolBar === "undefined") return; | ||
|
||
function shiftTabElements( | ||
sliderButton, | ||
direction, | ||
continuous = false, | ||
complete = null | ||
) { | ||
const $tabElements = $(sliderButton) | ||
.closest("div.jstTabs") | ||
.find("ul > li.tab-elements") | ||
.eq(0); | ||
|
||
// Calculate the amount of shift | ||
const shift = continuous ? 50 : $tabElements.width() / 2; | ||
|
||
// Shift | ||
$tabElements.animate( | ||
{ | ||
scrollLeft: | ||
$tabElements.scrollLeft() + shift * (direction === "left" ? -1 : 1), | ||
}, | ||
{ | ||
easing: continuous ? "linear" : "swing", | ||
queue: false, | ||
start: () => { | ||
if (continuous) { | ||
$(sliderButton).addClass("continuous"); | ||
} else { | ||
$(sliderButton).removeClass("continuous"); | ||
} | ||
}, | ||
complete: () => { | ||
setTimeout(() => { | ||
if ( | ||
continuous && | ||
$(sliderButton).hasClass("continuous") && | ||
$(sliderButton).is(":hover") && | ||
(direction === "left" | ||
? $tabElements.scrollLeft() > 0 | ||
: Math.ceil($tabElements.scrollLeft() + $tabElements.width()) < | ||
$tabElements[0].scrollWidth) | ||
) { | ||
shiftTabElements(sliderButton, direction, continuous, complete); | ||
} else { | ||
$(sliderButton).removeClass("continuous"); | ||
} | ||
}); | ||
if (typeof complete === "function") complete(); | ||
}, | ||
} | ||
); | ||
} | ||
|
||
function changeSliderButtonsVisibility(sliderButtons) { | ||
const $sliderButtons = $(sliderButtons); | ||
const tabElements = $sliderButtons.closest("ul").find("li.tab-elements")[0]; | ||
|
||
function isOverFlow() { | ||
return ( | ||
tabElements.offsetWidth < | ||
tabElements.scrollWidth - $sliderButtons.parent().width() | ||
); | ||
} | ||
|
||
$sliderButtons | ||
.toggle(isOverFlow()) | ||
.toggleClass("at-the-left", $(tabElements).scrollLeft() === 0) | ||
.toggleClass( | ||
"at-the-right", | ||
Math.ceil($(tabElements).scrollLeft() + $(tabElements).width()) >= | ||
tabElements.scrollWidth | ||
); | ||
} | ||
|
||
function addSliderButtonsToJstoolbar(tabsBlock) { | ||
const $tabsBlock = $(tabsBlock); | ||
if ($tabsBlock.find(".slider-buttons").length > 0) return; | ||
|
||
let shiftEventId = null; | ||
const mouseOverActionDelay = 1000; | ||
|
||
function generateButton(direction) { | ||
return $("<button/>") | ||
.attr("type", "button") | ||
.addClass(`icon shift-${direction}`) | ||
.on("click", (e) => { | ||
clearTimeout(shiftEventId); | ||
shiftTabElements(e.target, direction, false, () => { | ||
changeSliderButtonsVisibility($sliderButtons); | ||
}); | ||
}) | ||
.on("mouseover", (e) => { | ||
clearTimeout(shiftEventId); | ||
shiftEventId = setTimeout(() => { | ||
shiftTabElements(e.target, direction, true, () => { | ||
changeSliderButtonsVisibility($sliderButtons); | ||
}); | ||
}, mouseOverActionDelay); | ||
}) | ||
.on("mouseout", () => { | ||
clearTimeout(shiftEventId); | ||
}); | ||
} | ||
|
||
// Generate slider buttons | ||
const $sliderButtons = $("<div/>") | ||
.addClass("slider-buttons") | ||
.addClass("jstElements") | ||
.append(generateButton("left")) | ||
.append(generateButton("right")); | ||
|
||
// Append slider buttons to jsToolBar | ||
$tabsBlock.children("ul").append($("<li/>").append($sliderButtons)); | ||
|
||
// Dynamically control the visibility of slider using ResizeObserver | ||
new ResizeObserver(() => { | ||
const $sliderButtons = $tabsBlock.find(".slider-buttons"); | ||
changeSliderButtonsVisibility($sliderButtons); | ||
}).observe($tabsBlock.find("li.tab-elements")[0]); | ||
|
||
// Initial application | ||
setTimeout(changeSliderButtonsVisibility($sliderButtons)); | ||
} | ||
|
||
// Trigger to initialize the jsToolBar Slider | ||
const initJstoolbarSlider = { | ||
type: "init_jstoolbar_slider", | ||
}; | ||
|
||
// Add to toolbar | ||
jsToolBar.prototype.elements = { | ||
...jsToolBar.prototype.elements, | ||
init_jstoolbar_slider: initJstoolbarSlider, | ||
}; | ||
|
||
jsToolBar.prototype.init_jstoolbar_slider = function () { | ||
addSliderButtonsToJstoolbar(this.tabsBlock); | ||
}; | ||
})(); |
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,42 @@ | ||
@media screen and (max-width: 899px) { | ||
#content .jstTabs { | ||
width: 100%; | ||
} | ||
} | ||
#content .jstTabs.tabs ul { | ||
min-width: unset; | ||
display: flex; | ||
flex-direction: row; | ||
width: 99%; | ||
} | ||
#content .jstTabs.tabs ul > li { | ||
flex: 0 0 auto; | ||
} | ||
#content .jstTabs.tabs ul > li.tab-elements { | ||
flex: 1 1 auto; | ||
overflow: hidden; | ||
} | ||
#content .jstTabs.tabs .slider-buttons { | ||
padding-right: 0; | ||
padding-left: 0; | ||
} | ||
#content .jstTabs.tabs .slider-buttons button { | ||
position: static; | ||
} | ||
div.jstElements button.shift-left, | ||
div.jstElements button.shift-right { | ||
right: 28px; | ||
border-top-left-radius: 3px; | ||
background-color: #eee; | ||
} | ||
div.jstElements button.shift-left { | ||
background: url(../../../images/arrow_left.png) no-repeat 50% 50% !important; | ||
} | ||
div.jstElements button.shift-right { | ||
background: url(../../../images/arrow_right.png) no-repeat 50% 50% !important; | ||
} | ||
div.jstElements.slider-buttons.at-the-left button.shift-left, | ||
div.jstElements.slider-buttons.at-the-right button.shift-right { | ||
background-color: #ccc !important; | ||
opacity: 1; | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,10 @@ | ||
require_dependency File.expand_path("../lib/jstoolbar_slider/hooks.rb", __FILE__) | ||
|
||
Redmine::Plugin.register :redmine_jstoolbar_slider do | ||
name "Redmine jsToolbar Slider plugin" | ||
author "sk-ys" | ||
description "This is a plugin for Redmine" | ||
version "0.1.0" | ||
url "https://github.com/sk-ys/redmine_jstoolbar_slider" | ||
author_url "https://github.com/sk-ys" | ||
end |
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,3 @@ | ||
class JstoolbarSlider::Hooks < Redmine::Hook::ViewListener | ||
render_on :view_layouts_base_html_head, :partial => "jstoolbar_slider/base" | ||
end |