Compare commits

...

15 Commits

Author SHA1 Message Date
Simon Vieille cc2ab04035 release v1.12.0 2020-09-12 16:44:05 +02:00
Simon Vieille 17a57f3685 Merge branch 'feature/issue30-tab' into develop 2020-09-12 16:40:43 +02:00
Simon Vieille d41ecbbd9a add translations 2020-09-12 16:35:30 +02:00
Simon Vieille b6c6fc2486 add target _blank 2020-09-12 16:32:10 +02:00
Simon Vieille 918c55da3e add options to select apps that must be opend on new tab (UI) 2020-09-12 16:10:48 +02:00
Simon Vieille 385c27c691 add documentation 2020-09-11 13:46:48 +02:00
Simon Vieille 54d702ba9f add documentation 2020-09-11 13:46:25 +02:00
Simon Vieille c816c40c19 fix typo 2020-09-11 13:39:41 +02:00
Simon Vieille aad27cd8b4 release v1.11.0 2020-09-11 13:26:01 +02:00
Simon Vieille 96fb33b80b Merge branch 'feature/issue29-tab' into develop 2020-09-11 13:25:09 +02:00
Simon Vieille e10a5f1f62 fix issue with side menu header 2020-09-11 13:23:52 +02:00
Simon Vieille f133932884 add target _blank when the option is enabled 2020-09-11 13:23:40 +02:00
Simon Vieille e287e27375 add translations 2020-09-11 13:06:43 +02:00
Simon Vieille 9ae4d7ee48 add new option: open apps in new tab 2020-09-11 13:03:37 +02:00
Simon Vieille 624bb52ec4 release v1.10.0 2020-09-04 18:14:49 +02:00
19 changed files with 174 additions and 6 deletions
+2
View File
@@ -12,6 +12,8 @@ Comptatible with AppOrder.
* [How to contribute?](#how-to-contribute) * [How to contribute?](#how-to-contribute)
* [Screenshots](https://gitnet.fr/deblan/side_menu/src/branch/master/screenshots/) * [Screenshots](https://gitnet.fr/deblan/side_menu/src/branch/master/screenshots/)
You like this app and you want to support me? [Buy me a coffe](https://www.buymeacoffee.com/deblan) ☕
Installation and upgrade Installation and upgrade
------------------------ ------------------------
+2 -2
View File
@@ -2,7 +2,7 @@
<info> <info>
<id>side_menu</id> <id>side_menu</id>
<name>Side menu</name> <name>Side menu</name>
<summary>Move the top menu to the left side.</summary> <summary>Modify the display of the menu.</summary>
<description><![CDATA[Side menu allows you to modify the position of the main menu by creating a panel on the left of the interface or with a big menu on the top. <description><![CDATA[Side menu allows you to modify the position of the main menu by creating a panel on the left of the interface or with a big menu on the top.
You can also define apps that must be displayed in the top menu. Fully customisable. You can also define apps that must be displayed in the top menu. Fully customisable.
@@ -17,7 +17,7 @@ You can report a bug or request a feature by opening an issue.
]]></description> ]]></description>
<licence>agpl</licence> <licence>agpl</licence>
<author mail="contact@deblan.fr" homepage="https://www.deblan.io/">Simon Vieille</author> <author mail="contact@deblan.fr" homepage="https://www.deblan.io/">Simon Vieille</author>
<version>1.9.3</version> <version>1.12.0</version>
<namespace>SideMenu</namespace> <namespace>SideMenu</namespace>
<category>customization</category> <category>customization</category>
<website>https://gitnet.fr/deblan/side_menu</website> <website>https://gitnet.fr/deblan/side_menu</website>
+4
View File
@@ -64,3 +64,7 @@
font-size: 11px; font-size: 11px;
font-weight: normal; font-weight: normal;
} }
.side-menu-toggler {
cursor: pointer;
}
+4
View File
@@ -211,6 +211,10 @@
display: none; display: none;
} }
.side-menu-always-displayed #side-menu .side-menu-header {
height: 49px;
}
.side-menu-always-displayed #side-menu.open, .side-menu-always-displayed #side-menu.open,
.side-menu-always-displayed #side-menu.open .side-menu-apps-list, .side-menu-always-displayed #side-menu.open .side-menu-apps-list,
.side-menu-always-displayed #side-menu.open .side-menu-header, .side-menu-always-displayed #side-menu.open .side-menu-header,
+10
View File
@@ -54,6 +54,7 @@ class JsController extends Controller
{ {
$user = OC::$server[IUserSession::class]->getUser(); $user = OC::$server[IUserSession::class]->getUser();
$topMenuApps = (array) json_decode($this->config->getAppValue('side_menu', 'top-menu-apps', '[]'), true); $topMenuApps = (array) json_decode($this->config->getAppValue('side_menu', 'top-menu-apps', '[]'), true);
$targetBlankApps = (array) json_decode($this->config->getAppValue('side_menu', 'target-blank-apps', '[]'), true);
if ($user) { if ($user) {
$userTopMenuApps = (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'top-menu-apps', '[]'), true); $userTopMenuApps = (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'top-menu-apps', '[]'), true);
@@ -61,8 +62,16 @@ class JsController extends Controller
if (!empty($userTopMenuApps)) { if (!empty($userTopMenuApps)) {
$topMenuApps = $userTopMenuApps; $topMenuApps = $userTopMenuApps;
} }
$userTargetBlankMode = (int) $this->config->getUserValue($user->getUid(), 'side_menu', 'target-blank-mode', '1');
$userTargetBlankApps = (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'target-blank-apps', '[]'), true);
if ($userTargetBlankMode === 2) {
$targetBlankApps = $userTargetBlankApps;
}
} }
$parameters = [ $parameters = [
'opener-position' => $this->config->getAppValue('side_menu', 'opener-position', 'before'), 'opener-position' => $this->config->getAppValue('side_menu', 'opener-position', 'before'),
'opener-hover' => (bool) $this->config->getAppValue('side_menu', 'opener-hover', '0'), 'opener-hover' => (bool) $this->config->getAppValue('side_menu', 'opener-hover', '0'),
@@ -73,6 +82,7 @@ class JsController extends Controller
'always-displayed' => (bool) $this->config->getAppValue('side_menu', 'always-displayed', '0'), 'always-displayed' => (bool) $this->config->getAppValue('side_menu', 'always-displayed', '0'),
'big-menu' => (bool) $this->config->getAppValue('side_menu', 'big-menu', '0'), 'big-menu' => (bool) $this->config->getAppValue('side_menu', 'big-menu', '0'),
'top-menu-apps' => $topMenuApps, 'top-menu-apps' => $topMenuApps,
'target-blank-apps' => $targetBlankApps,
]; ];
$response = new TemplateResponse('side_menu', 'js/script', $parameters, 'blank'); $response = new TemplateResponse('side_menu', 'js/script', $parameters, 'blank');
@@ -65,6 +65,29 @@ class PersonalSettingController extends Controller
} }
} }
if ('target-blank-mode' === $name) {
$doSave = true;
if (!in_array($value, ['1', '2'])) {
$value = '1';
}
}
if ('target-blank-apps' === $name) {
$doSave = true;
$data = json_decode($value, true);
if (!is_array($data)) {
$doSave = false;
} else {
foreach ($data as $v) {
if (!is_string($v)) {
$doSave = false;
}
}
}
}
if ('top-menu-apps' === $name) { if ('top-menu-apps' === $name) {
$doSave = true; $doSave = true;
$data = json_decode($value, true); $data = json_decode($value, true);
+1
View File
@@ -83,6 +83,7 @@ class Admin implements ISettings
'hide-when-no-apps' => $this->config->getAppValue('side_menu', 'hide-when-no-apps', '0'), 'hide-when-no-apps' => $this->config->getAppValue('side_menu', 'hide-when-no-apps', '0'),
'size-icon' => $this->config->getAppValue('side_menu', 'size-icon', 'normal'), 'size-icon' => $this->config->getAppValue('side_menu', 'size-icon', 'normal'),
'size-text' => $this->config->getAppValue('side_menu', 'size-text', 'normal'), 'size-text' => $this->config->getAppValue('side_menu', 'size-text', 'normal'),
'target-blank-apps' => (array) json_decode($this->config->getAppValue('side_menu', 'target-blank-apps', '[]'), true),
'top-menu-apps' => (array) json_decode($this->config->getAppValue('side_menu', 'top-menu-apps', '[]'), true), 'top-menu-apps' => (array) json_decode($this->config->getAppValue('side_menu', 'top-menu-apps', '[]'), true),
'apps' => $this->appRepository->getVisibleApps(), 'apps' => $this->appRepository->getVisibleApps(),
]; ];
+2
View File
@@ -72,6 +72,8 @@ class Personal implements ISettings
$parameters = [ $parameters = [
'enabled' => $this->config->getUserValue($user->getUid(), 'side_menu', 'enabled', '1'), 'enabled' => $this->config->getUserValue($user->getUid(), 'side_menu', 'enabled', '1'),
'top-menu-apps' => (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'top-menu-apps', '[]'), true), 'top-menu-apps' => (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'top-menu-apps', '[]'), true),
'target-blank-mode' => $this->config->getUserValue($user->getUid(), 'side_menu', 'target-blank-mode', '1'),
'target-blank-apps' => (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'target-blank-apps', '[]'), true),
'apps' => $this->appRepository->getVisibleApps(), 'apps' => $this->appRepository->getVisibleApps(),
]; ];
Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 57 KiB

+4 -1
View File
@@ -26,7 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<ul class="side-menu-apps-list"> <ul class="side-menu-apps-list">
<li v-for="app in apps" v-bind:class="{'side-menu-app': true, 'active': app.active}"> <li v-for="app in apps" v-bind:class="{'side-menu-app': true, 'active': app.active}">
<a v-bind:href="app.href" v-bind:title="app.name"> <a v-bind:href="app.href" :target="targetBlankApps.indexOf(app.id) !== -1 ? '_blank' : undefined" v-bind:title="app.name">
<span class="side-menu-app-icon" v-html="app.icon"></span> <span class="side-menu-app-icon" v-html="app.icon"></span>
<span class="side-menu-app-text" v-html="app.name"></span> <span class="side-menu-app-text" v-html="app.name"></span>
</a> </a>
@@ -45,6 +45,7 @@ export default {
apps: [], apps: [],
logo: null, logo: null,
forceLightIcon: false, forceLightIcon: false,
targetBlank: false,
} }
}, },
methods: { methods: {
@@ -86,6 +87,7 @@ export default {
} }
this.apps.push({ this.apps.push({
id: dataId,
href: href, href: href,
name: trim(element.querySelector('span').innerHTML), name: trim(element.querySelector('span').innerHTML),
icon: svg, icon: svg,
@@ -119,6 +121,7 @@ export default {
this.retrieveApps() this.retrieveApps()
this.retrieveLogo() this.retrieveLogo()
this.forceLightIcon = document.querySelector('#side-menu-container').getAttribute('data-forcelighticon') == 1; this.forceLightIcon = document.querySelector('#side-menu-container').getAttribute('data-forcelighticon') == 1;
this.targetBlankApps = document.querySelector('#side-menu-container').getAttribute('data-targetblankapps').split(',');
const menu = document.querySelector('#appmenu') const menu = document.querySelector('#appmenu')
+4 -1
View File
@@ -28,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<ul class="side-menu-apps-list"> <ul class="side-menu-apps-list">
<li v-bind:class="{'side-menu-app': true, 'active': activeApp === appId}" v-for="(app, appId) in category.apps"> <li v-bind:class="{'side-menu-app': true, 'active': activeApp === appId}" v-for="(app, appId) in category.apps">
<a v-bind:href="app.href" v-bind:title="app.name"> <a v-bind:href="app.href" :target="targetBlankApps.indexOf(appId) !== -1 ? '_blank' : undefined" v-bind:title="app.name">
<img class="side-menu-app-icon" v-bind:src="app.icon"></span> <img class="side-menu-app-icon" v-bind:src="app.icon"></span>
<span class="side-menu-app-text" v-html="app.name"></span> <span class="side-menu-app-text" v-html="app.name"></span>
</a> </a>
@@ -50,6 +50,7 @@ export default {
return { return {
items: [], items: [],
activeApp: null, activeApp: null,
targetBlank: false,
} }
}, },
methods: { methods: {
@@ -79,6 +80,8 @@ export default {
}, },
}, },
mounted() { mounted() {
this.targetBlankApps = document.querySelector('#side-menu-container').getAttribute('data-targetblankapps').split(',');
this.retrieveApps() this.retrieveApps()
this.retrieveActiveApp() this.retrieveActiveApp()
} }
+11
View File
@@ -81,6 +81,10 @@ const saveSettings = (key) => {
} }
} }
const elementToggler = (element) => {
jQuery(element).toggle()
}
jQuery(document).ready(() => { jQuery(document).ready(() => {
elements = jQuery('.side-menu-setting') elements = jQuery('.side-menu-setting')
@@ -118,4 +122,11 @@ jQuery(document).ready(() => {
document.documentElement.style.setProperty('--side-menu-' + name, value) document.documentElement.style.setProperty('--side-menu-' + name, value)
}) })
jQuery('.side-menu-toggler').on('click', (event) => {
var target = jQuery(event.target)
var element = target.attr('data-target')
elementToggler(element)
})
}); });
+4
View File
@@ -52,3 +52,7 @@
"Not compatible with touch screens.": "Nicht kompatibel mit Touchscreens." "Not compatible with touch screens.": "Nicht kompatibel mit Touchscreens."
"Big menu": "Große Speisekarte" "Big menu": "Große Speisekarte"
"Live preview": "Live Vorschau" "Live preview": "Live Vorschau"
"Open apps in new tab": "Öffnen Sie Apps in einem neuen Tab"
"Use the global setting": "Verwenden Sie die globale Einstellung"
"Use my selection": "Verwenden Sie meine Auswahl"
"Show and hide the list of applications": "Ein- und Ausblenden der Anwendungsliste"
+4
View File
@@ -52,3 +52,7 @@
"Not compatible with touch screens.": "Incompatible avec les écrans tactiles." "Not compatible with touch screens.": "Incompatible avec les écrans tactiles."
"Big menu": "Menu large" "Big menu": "Menu large"
"Live preview": "Aperçu en direct" "Live preview": "Aperçu en direct"
"Open apps in new tab": "Ouvrir les applications dans un nouvel onglet"
"Use the global setting": "Utiliser la configuration globale"
"Use my selection": "Utiliser ma sélection"
"Show and hide the list of applications": "Afficher et masquer la liste des applications"
+4
View File
@@ -38,6 +38,10 @@ var updateTopMenu = function() {
appShown.push(app) appShown.push(app)
navigationApps.append(app.outerHTML) navigationApps.append(app.outerHTML)
} }
if (targetBlankApps.indexOf(dataId) !== -1) {
jQuery(app).children('a').attr('target', '_blank');
}
}) })
var rightHeaderWidth = jQuery('.header-right').outerWidth() var rightHeaderWidth = jQuery('.header-right').outerWidth()
+4
View File
@@ -14,6 +14,10 @@
sideMenuContainer.attr('data-forcelighticon', '1') sideMenuContainer.attr('data-forcelighticon', '1')
<?php endif; ?> <?php endif; ?>
sideMenuContainer.attr('data-targetblankapps', '<?php p(implode(',', $_['target-blank-apps'])) ?>')
var targetBlankApps = <?php echo json_encode($_['target-blank-apps']) ?>;
body.on('side-menu.apps', function(e, apps) { body.on('side-menu.apps', function(e, apps) {
<?php if ($_['hide-when-no-apps']): ?> <?php if ($_['hide-when-no-apps']): ?>
sideMenu = jQuery('#side-menu') sideMenu = jQuery('#side-menu')
+39 -1
View File
@@ -366,6 +366,38 @@ $choicesSizes = [
</select> </select>
</div> </div>
<div>
<label for="side-menu-target-blank">
<?php p($l->t('Open apps in new tab')); ?>
</label>
</div>
<p>
<a class="side-menu-toggler" data-target="#target-blank-apps" href="#_">
🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
</a>
</p>
<div class="side-menu-setting" data-name="target-blank-apps" id="target-blank-apps" data-checkbox style="display: none">
<?php foreach ($_['apps'] as $app): ?>
<div>
<input
type="checkbox"
name="target-blank-apps[]"
value="<?php echo $app['id'] ?>"
id="target-blank-app-<?php echo $app['id'] ?>"
<?php if (in_array($app['id'], $_['target-blank-apps'])): ?>checked<?php endif; ?>
/>
<label for="target-blank-app-<?php echo $app['id'] ?>">
<?php echo p($l->t($app['name'])); ?>
</label>
</div>
<?php endforeach; ?>
</div>
<br>
<div> <div>
<label for="side-menu-loader-enabled"> <label for="side-menu-loader-enabled">
<?php p($l->t('Loader enabled')); ?> <?php p($l->t('Loader enabled')); ?>
@@ -393,7 +425,13 @@ $choicesSizes = [
</label> </label>
</div> </div>
<div class="side-menu-setting" data-name="top-menu-apps" data-checkbox> <p>
<a class="side-menu-toggler" data-target="#top-menu-apps" href="#_">
🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
</a>
</p>
<div class="side-menu-setting" data-name="top-menu-apps" id="top-menu-apps" data-checkbox style="display: none">
<?php foreach ($_['apps'] as $app): ?> <?php foreach ($_['apps'] as $app): ?>
<div> <div>
<input <input
+52 -1
View File
@@ -52,6 +52,51 @@ $choicesYesNo = [
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
<div>
<label for="side-menu-target-blank">
<?php p($l->t('Open apps in new tab')); ?>
</label>
</div>
<div>
<?php $choices = [
'Use the global setting' => '1',
'Use my selection' => '2',
]; ?>
<select id="side-menu-loader-enabled" name="target-blank-mode" class="side-menu-setting" data-personal>
<?php foreach ($choices as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['target-blank-mode']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<p>
<a class="side-menu-toggler" data-target="#target-blank-apps" href="#_">
🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
</a>
</p>
<div class="side-menu-setting" data-name="target-blank-apps" id="target-blank-apps" data-personal data-checkbox style="display: none">
<?php foreach ($_['apps'] as $app): ?>
<div>
<input
type="checkbox"
name="target-blank-apps[]"
value="<?php echo $app['id'] ?>"
id="target-blank-app-<?php echo $app['id'] ?>"
<?php if (in_array($app['id'], $_['target-blank-apps'])): ?>checked<?php endif; ?>
/>
<label for="target-blank-app-<?php echo $app['id'] ?>">
<?php echo p($l->t($app['name'])); ?>
</label>
</div>
<?php endforeach; ?>
</div>
</div> </div>
<div class="section"> <div class="section">
@@ -70,7 +115,13 @@ $choicesYesNo = [
</em> </em>
</p> </p>
<div class="side-menu-setting" data-name="top-menu-apps" data-checkbox data-personal> <p>
<a class="side-menu-toggler" data-target="#top-menu-apps" href="#_">
🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
</a>
</p>
<div class="side-menu-setting" data-name="top-menu-apps" data-checkbox data-personal id="top-menu-apps" style="display: none">
<?php foreach ($_['apps'] as $app): ?> <?php foreach ($_['apps'] as $app): ?>
<div> <div>
<input <input