Compare commits

...

29 Commits

Author SHA1 Message Date
Simon Vieille 6be679c569 fix regression: apps does not open in the tab 2021-02-05 17:54:50 +01:00
Simon Vieille 0893ddd5fe release v1.22.0 2021-02-03 15:23:07 +01:00
Simon Vieille c893391065 update ui of admin and fix #53 2021-02-03 15:21:08 +01:00
Simon Vieille b06df8ad9f update ui of admin lists 2021-02-03 10:27:08 +01:00
Simon Vieille 13f7e63514 PSR 2 compliance 2021-02-03 10:15:59 +01:00
Simon Vieille 64da45e676 add feature: order categories 2021-02-03 10:14:03 +01:00
Simon Vieille 77e27bcc1a add code of conduct and update chat room link 2020-12-23 13:39:43 +01:00
Simon Vieille 99858d86c1 release v1.21.0 2020-12-03 13:34:57 +01:00
Simon Vieille 6984efdafd fix issue #51: add link on the logo 2020-12-03 13:33:28 +01:00
Simon Vieille 48d80edb0a update issue template 2020-11-08 12:32:19 +01:00
Simon Vieille b57743c61a add donation link 2020-11-06 18:17:17 +01:00
Simon Vieille a58ca57e46 release v1.20.1 2020-11-03 13:00:26 +01:00
Simon Vieille dc6ec4eb89 fix typo and translations 2020-11-03 13:00:09 +01:00
Simon Vieille 8588f1510f release v1.20.0 2020-11-03 12:20:01 +01:00
Simon Vieille 02825cee67 add option to hide apps (big menu display) 2020-11-03 12:16:36 +01:00
Simon Vieille 10e90df4b8 update issue templates 2020-11-01 14:13:54 +01:00
Simon Vieille 99590447e5 update issue templates 2020-11-01 13:53:19 +01:00
Simon Vieille b5e41ff96e update issue templates 2020-11-01 13:49:04 +01:00
Simon Vieille 680587e75c add documentation (related to #48) 2020-10-24 14:29:32 +02:00
Simon Vieille 9f7d6c931e add a script to import config 2020-10-23 18:25:08 +02:00
Simon Vieille 205a72f74d add documentation 2020-10-23 18:24:48 +02:00
Simon Vieille ef00aae51f update issue template 2020-10-23 11:51:28 +02:00
Simon Vieille b208c8cb19 release v1.19.1 2020-10-21 18:06:00 +02:00
Simon Vieille 0e5cd135b4 fix issue #47 2020-10-21 18:05:36 +02:00
Simon Vieille 854beb8078 release v1.19.0 2020-10-19 18:26:17 +02:00
Simon Vieille 709f938f48 update screenshots 2020-10-19 18:24:08 +02:00
Simon Vieille 80700cac32 add option: the menu is enabled by default for users 2020-10-19 13:44:07 +02:00
Simon Vieille a71a8c7208 add documentation 2020-10-16 13:42:23 +02:00
Simon Vieille cf80c3512c add licence 2020-10-16 11:46:25 +02:00
33 changed files with 1918 additions and 369 deletions
+16
View File
@@ -0,0 +1,16 @@
---
name: "New feature"
about: "Use this template if you want to request a feature"
title: "[FEATURE] "
labels:
- enhancement
---
## Feature
### Description
...
### Benefits
...
+32
View File
@@ -0,0 +1,32 @@
---
name: "New issue"
about: "Use this template if you have a bug"
title: "[BUG] "
labels:
- bug
---
## Issue
### Environment
* Custom menu version:
* Nextcloud version:
* PHP version:
* Web server (Nginx, Apache2):
* Web browser and version (Firefox 80, Google Chrome 74, etc):
```
Insert your configuration here. You can export the configuration using the admin page.
```
### Steps to reproduce
...
### Observed Results
...
### Expected Results
...
+1027
View File
File diff suppressed because one or more lines are too long
-35
View File
@@ -1,35 +0,0 @@
## Feature
### Description
...
### Benefits
...
---
## Issue
### Environment
* Side menu version: ...
* Nextcloud version: ...
* PHP version: ...
* Web server (Nginx, Apache2): ...
* Web browser and version (Firefox 80, Google Chrome 74, etc): ...
### Steps to reproduce
* ...
* ...
* ...
### Observed Results
...
### Expected Results
...
+16 -3
View File
@@ -12,16 +12,29 @@ 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 coffee](https://www.buymeacoffee.com/deblan) ☕ You like this app and you want to support me? ☕ [Buy me a coffee](https://www.buymeacoffee.com/deblan) or [Donate with liberapay](https://liberapay.com/deblan)
Requirements
------------
* PHP >= 7.3
* App `theming` enabled
Installation and upgrade Installation and upgrade
------------------------ ------------------------
Custom menu is available from the app store. If you want to install it from source: go to https://gitnet.fr/deblan/side_menu/releases and download the last release (side_menu_vX.Y.Z.zip). Copy the content into `apps`. Custom menu is available from the app store.
```
$ cd /path/to/nextcloud
$ php occ app:install side_menu
```
If you want to install it from source, go to https://gitnet.fr/deblan/side_menu/releases and copy the link to the last release (side_menu_vX.Y.Z.tar.gz). Then:
``` ```
$ cd /path/to/nextcloud/apps $ cd /path/to/nextcloud/apps
$ unzip /path/to/side_menu_vX.Y.Z.zip # tar xvf /path/to/side_menu_vX.Y.Z.tar.gz $ curl -sS https://gitnet.fr/attachments/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | tar xvfz -
``` ```
Administrators can edit many settings using the administration page. Administrators can edit many settings using the administration page.
+11 -5
View File
@@ -15,12 +15,18 @@ Comptatible with AppOrder.
You can report a bug or request a feature by opening an issue. You can report a bug or request a feature by opening an issue.
If you like this application and want to support the development: Requirements:
* ☕ [Buy me a coffee](https://www.buymeacoffee.com/deblan) * PHP >= 7.3
* 😃 [Leave a comment](https://apps.nextcloud.com/apps/side_menu#comments) * App `theming` enabled
If you like this application and if you want to support the development:
* [Buy me a coffee](https://www.buymeacoffee.com/deblan)
* [Donate with liberapay](https://liberapay.com/deblan)
* [Leave a comment](https://apps.nextcloud.com/apps/side_menu#comments)
]]></description> ]]></description>
<version>1.18.0</version> <version>1.22.0</version>
<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>
<namespace>SideMenu</namespace> <namespace>SideMenu</namespace>
@@ -30,7 +36,7 @@ If you like this application and want to support the development:
</documentation> </documentation>
<category>customization</category> <category>customization</category>
<website>https://gitnet.fr/deblan/side_menu</website> <website>https://gitnet.fr/deblan/side_menu</website>
<discussion>https://matrix.to/#/!GhfQePnOSPYpYEunWM:neutralnetwork.org</discussion> <discussion>https://matrix.to/#/!TFPucDATKODpHNVAtu:neutralnetwork.org?via=neutralnetwork.org</discussion>
<bugs>https://gitnet.fr/deblan/side_menu/issues</bugs> <bugs>https://gitnet.fr/deblan/side_menu/issues</bugs>
<repository type="git">https://gitnet.fr/deblan/side_menu</repository> <repository type="git">https://gitnet.fr/deblan/side_menu</repository>
<screenshot>https://gitnet.fr/deblan/side_menu/raw/branch/master/screenshots/nc19_default_menu.png</screenshot> <screenshot>https://gitnet.fr/deblan/side_menu/raw/branch/master/screenshots/nc19_default_menu.png</screenshot>
+6
View File
@@ -1,4 +1,10 @@
<?php <?php
/**
* Generates l10n files using Yaml.
*
* Usage:
* php bin/generate_l10n.php
*/
function generateJsContent($translations) function generateJsContent($translations)
{ {
+24
View File
@@ -0,0 +1,24 @@
<?php
/**
* Imports a json configuration into a sqlite database.
*
* Usage:
* php bin/import_config.php /path/to/config.json /path/to/owncloud.db
*/
$configFile = $argv[1];
$databaseFile = $argv[2];
$content = file_get_contents($configFile);
$config = json_decode($content, true);
$pdo = new \Pdo(sprintf('sqlite:%s', $databaseFile));
$stmt = $pdo->prepare('UPDATE oc_appconfig SET configvalue=:value WHERE configkey=:key and appid=:appId');
foreach ($config as $key => $value) {
$stmt->execute([
'appId' => 'side_menu',
'key' => $key,
'value' => $value,
]);
}
+43
View File
@@ -68,3 +68,46 @@
.side-menu-toggler { .side-menu-toggler {
cursor: pointer; cursor: pointer;
} }
.side-menu-setting-list {
margin: 10px 4px 4px 0px;
}
.side-menu-setting-list-item {
padding: 5px 10px;
border: 1px solid var(--color-border-dark);
max-width: 300px;
margin: -1px 0 0 0;
cursor: pointer;
}
.side-menu-setting.arrow {
color: #ccc;
padding-right: 5px;
}
.side-menu-setting-list-item input {
min-height: auto;
margin-top: -1px;
}
.side-menu-setting-table {
display: table;
width: 100%;
}
.side-menu-setting-row {
display: table;
}
.side-menu-setting-label {
display: table-cell;
width: 400px;
padding-right: 20px;
}
.side-menu-setting-form {
display: table-cell;
width: 300px;
}
+16 -2
View File
@@ -6,6 +6,7 @@ use OC;
use OC\Security\CSP\ContentSecurityPolicyNonceManager; use OC\Security\CSP\ContentSecurityPolicyNonceManager;
use OC\User\User; use OC\User\User;
use OCA\SideMenu\Service\AppRepository; use OCA\SideMenu\Service\AppRepository;
use OCA\SideMenu\Service\CategoryRepository;
use OCA\SideMenu\Service\ConfigProxy; use OCA\SideMenu\Service\ConfigProxy;
use OCP\AppFramework\App; use OCP\AppFramework\App;
use OCP\IUserSession; use OCP\IUserSession;
@@ -58,7 +59,16 @@ class Application extends App
$isForced = (bool) $this->config->getAppValue(self::APP_ID, 'force', '0'); $isForced = (bool) $this->config->getAppValue(self::APP_ID, 'force', '0');
if (null !== $this->user && !$isForced) { if (null !== $this->user && !$isForced) {
$enabled = (bool) $this->config->getUserValue($this->user->getUid(), self::APP_ID, 'enabled', '1'); $enabled = (bool) $this->config->getUserValue(
$this->user->getUid(),
self::APP_ID,
'enabled',
$this->config->getAppValue(
self::APP_ID,
'default-enabled',
'1'
)
);
} }
return $enabled; return $enabled;
@@ -75,8 +85,12 @@ class Application extends App
return new AppRepository(); return new AppRepository();
}); });
$container->registerService('CategoryRepository', function (ContainerInterface $c) {
return new CategoryRepository();
});
$container->registerService('ConfigProxy', function (ContainerInterface $c) { $container->registerService('ConfigProxy', function (ContainerInterface $c) {
return new ConfigProxy($this->config); return new ConfigProxy();
}); });
} }
+5
View File
@@ -97,6 +97,7 @@ class JsController extends Controller
$targetBlankApps = $this->config->getAppValueArray('target-blank-apps', '[]'); $targetBlankApps = $this->config->getAppValueArray('target-blank-apps', '[]');
$useAvatar = $this->config->getAppValueBool('use-avatar', '0'); $useAvatar = $this->config->getAppValueBool('use-avatar', '0');
$isForced = $this->config->getAppValueBool('force', '0'); $isForced = $this->config->getAppValueBool('force', '0');
$addLogoLink = $this->config->getAppValueBool('add-logo-link', '1');
$avatar = null; $avatar = null;
$settings = null; $settings = null;
@@ -141,6 +142,8 @@ class JsController extends Controller
} }
} }
$indexUrl = OC::$server->getURLGenerator()->linkTo('', 'index.php');
return [ return [
'opener-position' => $this->config->getAppValue('opener-position', 'before'), 'opener-position' => $this->config->getAppValue('opener-position', 'before'),
'opener-hover' => $this->config->getAppValueBool('opener-hover', '0'), 'opener-hover' => $this->config->getAppValueBool('opener-hover', '0'),
@@ -150,11 +153,13 @@ class JsController extends Controller
'loader-enabled' => $this->config->getAppValueBool('loader-enabled', '1'), 'loader-enabled' => $this->config->getAppValueBool('loader-enabled', '1'),
'always-displayed' => $this->config->getAppValueBool('always-displayed', '0'), 'always-displayed' => $this->config->getAppValueBool('always-displayed', '0'),
'big-menu' => $this->config->getAppValueBool('big-menu', '0'), 'big-menu' => $this->config->getAppValueBool('big-menu', '0'),
'big-menu-hidden-apps' => $this->config->getAppValueArray('big-menu-hidden-apps', '[]'),
'avatar' => $avatar, 'avatar' => $avatar,
'top-menu-apps' => $topMenuApps, 'top-menu-apps' => $topMenuApps,
'target-blank-apps' => $targetBlankApps, 'target-blank-apps' => $targetBlankApps,
'settings' => $settings, 'settings' => $settings,
'logo' => $this->themingDefaults->getLogo(), 'logo' => $this->themingDefaults->getLogo(),
'logo-link' => $addLogoLink ? $indexUrl : null,
]; ];
} }
} }
+25 -42
View File
@@ -21,13 +21,11 @@ namespace OCA\SideMenu\Controller;
use OC; use OC;
use OC\App\AppStore\Fetcher\CategoryFetcher; use OC\App\AppStore\Fetcher\CategoryFetcher;
use OC\URLGenerator; use OC\URLGenerator;
use OCA\SideMenu\AppInfo\Application;
use OCA\SideMenu\Service\AppRepository; use OCA\SideMenu\Service\AppRepository;
use OCA\SideMenu\Service\CategoryRepository;
use OCA\SideMenu\Service\ConfigProxy; use OCA\SideMenu\Service\ConfigProxy;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IRequest; use OCP\IRequest;
use OCP\IUserSession; use OCP\IUserSession;
use OCP\L10N\IFactory; use OCP\L10N\IFactory;
@@ -39,11 +37,6 @@ class NavController extends Controller
*/ */
protected $config; protected $config;
/**
* @var IConfig
*/
protected $iConfig;
/** /**
* @var AppRepository * @var AppRepository
*/ */
@@ -67,20 +60,17 @@ class NavController extends Controller
public function __construct( public function __construct(
string $appName, string $appName,
IRequest $request, IRequest $request,
IConfig $iConfig,
ConfigProxy $config, ConfigProxy $config,
AppRepository $appRepository, AppRepository $appRepository,
CategoryFetcher $categoryFetcher, CategoryRepository $categoryRepository,
URLGenerator $router, URLGenerator $router,
IL10N $trans,
IFactory $l10nFactory IFactory $l10nFactory
) { ) {
parent::__construct($appName, $request); parent::__construct($appName, $request);
$this->config = $config; $this->config = $config;
$this->iConfig = $iConfig;
$this->appRepository = $appRepository; $this->appRepository = $appRepository;
$this->categoryFetcher = $categoryFetcher; $this->categoryRepository = $categoryRepository;
$this->l10nFactory = $l10nFactory; $this->l10nFactory = $l10nFactory;
$this->router = $router; $this->router = $router;
} }
@@ -94,13 +84,7 @@ class NavController extends Controller
*/ */
public function items() public function items()
{ {
$apps = $this->appRepository->getVisibleApps();
$currentLanguage = substr($this->l10nFactory->findLanguage(), 0, 2);
$externalSitesInTopMenu = $this->config->getAppValueBool('external-sites-in-top-menu', '0');
$user = OC::$server[IUserSession::class]->getUser(); $user = OC::$server[IUserSession::class]->getUser();
$isForced = $this->config->getAppValueBool('force', '0');
$appsCategories = [];
$categoriesAppsCount = [];
$items = []; $items = [];
if (!$user) { if (!$user) {
@@ -109,39 +93,28 @@ class NavController extends Controller
]); ]);
} }
$categoriesLabels = $this->config->getAppValueArray('cache-categories', '[]'); $apps = $this->appRepository->getVisibleApps();
$categoriesLabels = $this->categoryRepository->getOrderedCategories();
if (empty($categoriesLabels)) { $hiddenApps = $this->config->getAppValueArray('big-menu-hidden-apps', '[]');
$categoriesLabels = $this->categoryFetcher->get(); $isForced = $this->config->getAppValueBool('force', '0');
$this->iConfig->setAppValue(Application::APP_ID, 'cache-categories', json_encode($categoriesLabels));
}
$topMenuApps = $this->config->getAppValueArray('top-menu-apps', '[]'); $topMenuApps = $this->config->getAppValueArray('top-menu-apps', '[]');
$userTopMenuApps = $this->config->getUserValueArray($user, 'top-menu-apps', '[]'); $userTopMenuApps = $this->config->getUserValueArray($user, 'top-menu-apps', '[]');
$appsCategories = [];
$categoriesAppsCount = [];
if (!$isForced && !empty($userTopMenuApps)) { if (!$isForced && !empty($userTopMenuApps)) {
$topMenuApps = $userTopMenuApps; $topMenuApps = $userTopMenuApps;
} }
foreach ($categoriesLabels as $k => $category) {
$categoriesLabels[$category['id']] = $category['translations'][$currentLanguage]['name'] ?? $category['translations']['en']['name'];
unset($categoriesLabels[$k]);
}
$categoriesLabels['external_links'] = $this->l10nFactory->get('external')->t('External sites');
$items['other'] = [
'name' => '',
'apps' => [],
];
foreach ($apps as $app) { foreach ($apps as $app) {
if (in_array($app['id'], $topMenuApps)) { if (in_array($app['id'], $topMenuApps)) {
continue; continue;
} }
if (in_array($app['id'], $hiddenApps)) {
continue;
}
$categories = (array) $app['category']; $categories = (array) $app['category'];
$appsCategories[$app['id']] = []; $appsCategories[$app['id']] = [];
@@ -153,6 +126,7 @@ class NavController extends Controller
if (!isset($items[$category])) { if (!isset($items[$category])) {
$items[$category] = [ $items[$category] = [
'name' => $categoriesLabels[$category] ?? $category, 'name' => $categoriesLabels[$category] ?? $category,
'categoryId' => $category,
'apps' => [], 'apps' => [],
]; ];
} }
@@ -211,8 +185,17 @@ class NavController extends Controller
} }
} }
usort($items, function ($a, $b) { usort($items, function ($a, $b) use ($categoriesLabels) {
return ($a['name'] < $b['name']) ? -1 : 1; foreach ($categoriesLabels as $key => $value) {
if ($a['categoryId'] === $key) {
return -1;
}
if ($b['categoryId'] === $key) {
return 1;
}
}
return 0;
}); });
return new JSONResponse([ return new JSONResponse([
+2 -2
View File
@@ -18,13 +18,13 @@
namespace OCA\SideMenu\Controller; namespace OCA\SideMenu\Controller;
use OCA\SideMenu\AppInfo\Application;
use OCA\SideMenu\Service\ConfigProxy;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\Response;
use OCP\IConfig; use OCP\IConfig;
use OCP\IRequest; use OCP\IRequest;
use OCP\IUserSession; use OCP\IUserSession;
use OCA\SideMenu\AppInfo\Application;
use OCA\SideMenu\Service\ConfigProxy;
class PersonalSettingController extends Controller class PersonalSettingController extends Controller
{ {
+99
View File
@@ -0,0 +1,99 @@
<?php
namespace OCA\SideMenu\Service;
use OC\App\AppStore\Fetcher\CategoryFetcher;
use OCA\SideMenu\AppInfo\Application;
use OCP\IConfig;
use OCP\L10N\IFactory;
/**
* class CategoryRepository.
*
* @author Simon Vieille <simon@deblan.fr>
*/
class CategoryRepository
{
/**
* @var CategoryFetcher
*/
protected $categoryFetcher;
/**
* @var IFactory
*/
protected $l10nFactory;
/**
* @var ConfigProxy
*/
protected $config;
/**
* @var IConfig
*/
protected $iConfig;
public function __construct(
CategoryFetcher $categoryFetcher,
ConfigProxy $config,
IConfig $iConfig,
IFactory $l10nFactory
) {
$this->categoryFetcher = $categoryFetcher;
$this->l10nFactory = $l10nFactory;
$this->config = $config;
$this->iConfig = $iConfig;
}
/**
* Retrieves categories.
*
* @return array
*/
public function getOrderedCategories()
{
$currentLanguage = substr($this->l10nFactory->findLanguage(), 0, 2);
$type = $this->config->getAppValue('categories-order-type', 'default');
$order = $this->config->getAppValueArray('categories-order', '[]');
$categoriesLabels = $this->config->getAppValueArray('cache-categories', '[]');
if (empty($categoriesLabels)) {
$categoriesLabels = $this->categoryFetcher->get();
$this->iConfig->setAppValue(Application::APP_ID, 'cache-categories', json_encode($categoriesLabels));
}
foreach ($categoriesLabels as $k => $category) {
$categoriesLabels[$category['id']] = $category['translations'][$currentLanguage]['name'] ?? $category['translations']['en']['name'];
unset($categoriesLabels[$k]);
}
$categoriesLabels['external_links'] = $this->l10nFactory->get('external')->t('External sites');
$categoriesLabels['other'] = '';
asort($categoriesLabels);
if ('custom' === $type) {
$ordered = [];
foreach ($order as $id) {
if (isset($categoriesLabels[$id])) {
$ordered[$id] = $categoriesLabels[$id];
}
}
foreach ($categoriesLabels as $id => $value) {
if (!isset($ordered[$id])) {
$ordered[$id] = $value;
}
}
$categoriesLabels = $ordered;
}
return $categoriesLabels;
}
}
+20 -2
View File
@@ -20,6 +20,7 @@ namespace OCA\SideMenu\Settings;
use OCA\SideMenu\AppInfo\Application; use OCA\SideMenu\AppInfo\Application;
use OCA\SideMenu\Service\AppRepository; use OCA\SideMenu\Service\AppRepository;
use OCA\SideMenu\Service\CategoryRepository;
use OCA\SideMenu\Service\ConfigProxy; use OCA\SideMenu\Service\ConfigProxy;
use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\TemplateResponse;
use OCP\IL10N; use OCP\IL10N;
@@ -48,12 +49,23 @@ class Admin implements ISettings
*/ */
private $appRepository; private $appRepository;
public function __construct(IL10N $l, ILogger $logger, ConfigProxy $config, AppRepository $appRepository) /**
{ * @var CategoryRepository
*/
private $categoryRepository;
public function __construct(
IL10N $l,
ILogger $logger,
ConfigProxy $config,
AppRepository $appRepository,
CategoryRepository $categoryRepository
) {
$this->l = $l; $this->l = $l;
$this->logger = $logger; $this->logger = $logger;
$this->config = $config; $this->config = $config;
$this->appRepository = $appRepository; $this->appRepository = $appRepository;
$this->categoryRepository = $categoryRepository;
} }
/** /**
@@ -77,7 +89,9 @@ class Admin implements ISettings
'opener' => $this->config->getAppValue('opener', 'side-menu-opener'), 'opener' => $this->config->getAppValue('opener', 'side-menu-opener'),
'always-displayed' => $this->config->getAppValue('always-displayed', '0'), 'always-displayed' => $this->config->getAppValue('always-displayed', '0'),
'big-menu' => $this->config->getAppValue('big-menu', '0'), 'big-menu' => $this->config->getAppValue('big-menu', '0'),
'big-menu-hidden-apps' => $this->config->getAppValueArray('big-menu-hidden-apps', '[]'),
'display-logo' => $this->config->getAppValue('display-logo', '1'), 'display-logo' => $this->config->getAppValue('display-logo', '1'),
'add-logo-link' => $this->config->getAppValue('add-logo-link', '1'),
'use-avatar' => $this->config->getAppValue('use-avatar', '0'), 'use-avatar' => $this->config->getAppValue('use-avatar', '0'),
'opener-position' => $this->config->getAppValue('opener-position', 'before'), 'opener-position' => $this->config->getAppValue('opener-position', 'before'),
'opener-hover' => $this->config->getAppValue('opener-hover', '0'), 'opener-hover' => $this->config->getAppValue('opener-hover', '0'),
@@ -89,7 +103,11 @@ class Admin implements ISettings
'force' => $this->config->getAppValue('force', '0'), 'force' => $this->config->getAppValue('force', '0'),
'target-blank-apps' => $this->config->getAppValueArray('target-blank-apps', '[]'), 'target-blank-apps' => $this->config->getAppValueArray('target-blank-apps', '[]'),
'top-menu-apps' => $this->config->getAppValueArray('top-menu-apps', '[]'), 'top-menu-apps' => $this->config->getAppValueArray('top-menu-apps', '[]'),
'default-enabled' => $this->config->getAppValue('default-enabled', '1'),
'categories-order-type' => $this->config->getAppValue('categories-order-type', 'default'),
'categories-order' => $this->config->getAppValueArray('categories-order', '[]'),
'apps' => $this->appRepository->getVisibleApps(), 'apps' => $this->appRepository->getVisibleApps(),
'categories' => $this->categoryRepository->getOrderedCategories(),
]; ];
return new TemplateResponse(Application::APP_ID, 'settings/admin-form', $parameters, ''); return new TemplateResponse(Application::APP_ID, 'settings/admin-form', $parameters, '');
+4 -8
View File
@@ -18,10 +18,10 @@
namespace OCA\SideMenu\Settings; namespace OCA\SideMenu\Settings;
use OCA\SideMenu\AppInfo\Application;
use OCP\IL10N; use OCP\IL10N;
use OCP\IURLGenerator; use OCP\IURLGenerator;
use OCP\Settings\IIconSection; use OCP\Settings\IIconSection;
use OCA\SideMenu\AppInfo\Application;
class AdminSection implements IIconSection class AdminSection implements IIconSection
{ {
@@ -35,10 +35,6 @@ class AdminSection implements IIconSection
*/ */
private $url; private $url;
/**
* @param IURLGenerator $url
* @param IL10N $l
*/
public function __construct(IURLGenerator $url, IL10N $l) public function __construct(IURLGenerator $url, IL10N $l)
{ {
$this->url = $url; $this->url = $url;
@@ -47,7 +43,7 @@ class AdminSection implements IIconSection
/** /**
* returns the ID of the section. It is supposed to be a lower case string, * returns the ID of the section. It is supposed to be a lower case string,
* e.g. 'ldap' * e.g. 'ldap'.
* *
* @returns string * @returns string
*/ */
@@ -69,8 +65,8 @@ class AdminSection implements IIconSection
/** /**
* @return int whether the form should be rather on the top or bottom of * @return int whether the form should be rather on the top or bottom of
* the settings navigation. The sections are arranged in ascending order of * the settings navigation. The sections are arranged in ascending order of
* the priority values. It is required to return a value between 0 and 99. * the priority values. It is required to return a value between 0 and 99.
* *
* E.g.: 70 * E.g.: 70
*/ */
+5 -1
View File
@@ -72,7 +72,11 @@ class Personal implements ISettings
$parameters = [ $parameters = [
'force' => $this->config->getAppValueBool('force', '0'), 'force' => $this->config->getAppValueBool('force', '0'),
'enabled' => $this->config->getUserValue($user, 'enabled', '1'), 'enabled' => $this->config->getUserValue(
$user,
'enabled',
$this->config->getAppValue('default-enabled', '1')
),
'top-menu-apps' => $this->config->getUserValueArray($user, 'top-menu-apps', '[]'), 'top-menu-apps' => $this->config->getUserValueArray($user, 'top-menu-apps', '[]'),
'target-blank-mode' => $this->config->getUserValue($user, 'target-blank-mode', '1'), 'target-blank-mode' => $this->config->getUserValue($user, 'target-blank-mode', '1'),
'target-blank-apps' => $this->config->getUserValueArray($user, 'target-blank-apps', '[]'), 'target-blank-apps' => $this->config->getUserValueArray($user, 'target-blank-apps', '[]'),
+4 -8
View File
@@ -18,10 +18,10 @@
namespace OCA\SideMenu\Settings; namespace OCA\SideMenu\Settings;
use OCA\SideMenu\AppInfo\Application;
use OCP\IL10N; use OCP\IL10N;
use OCP\IURLGenerator; use OCP\IURLGenerator;
use OCP\Settings\IIconSection; use OCP\Settings\IIconSection;
use OCA\SideMenu\AppInfo\Application;
class PersonalSection implements IIconSection class PersonalSection implements IIconSection
{ {
@@ -35,10 +35,6 @@ class PersonalSection implements IIconSection
*/ */
private $url; private $url;
/**
* @param IURLGenerator $url
* @param IL10N $l
*/
public function __construct(IURLGenerator $url, IL10N $l) public function __construct(IURLGenerator $url, IL10N $l)
{ {
$this->url = $url; $this->url = $url;
@@ -47,7 +43,7 @@ class PersonalSection implements IIconSection
/** /**
* returns the ID of the section. It is supposed to be a lower case string, * returns the ID of the section. It is supposed to be a lower case string,
* e.g. 'ldap' * e.g. 'ldap'.
* *
* @returns string * @returns string
*/ */
@@ -69,8 +65,8 @@ class PersonalSection implements IIconSection
/** /**
* @return int whether the form should be rather on the top or bottom of * @return int whether the form should be rather on the top or bottom of
* the settings navigation. The sections are arranged in ascending order of * the settings navigation. The sections are arranged in ascending order of
* the priority values. It is required to return a value between 0 and 99. * the priority values. It is required to return a value between 0 and 99.
* *
* E.g.: 70 * E.g.: 70
*/ */
Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 172 KiB

+16
View File
@@ -1,3 +1,19 @@
<!--
@license GNU AGPL version 3 or any later version
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template> <template>
<button class="side-menu-opener side-menu-closer"></button> <button class="side-menu-opener side-menu-closer"></button>
</template> </template>
+16
View File
@@ -1,3 +1,19 @@
<!--
@license GNU AGPL version 3 or any later version
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template> <template>
<div class="side-menu-loader"> <div class="side-menu-loader">
<svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg"> <svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg">
+24 -1
View File
@@ -1,6 +1,25 @@
<!--
@license GNU AGPL version 3 or any later version
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template> <template>
<div v-bind:class="classes"> <div v-bind:class="classes">
<img v-bind:src="image"> <a v-if="link !== null" v-bind:href="link">
<img v-bind:src="image">
</a>
<img v-else v-bind:src="image">
</div> </div>
</template> </template>
@@ -12,6 +31,10 @@ export default {
type: String, type: String,
required: true required: true
}, },
link: {
type: String,
required: false
},
classes: { classes: {
type: Object, type: Object,
required: true required: true
+16
View File
@@ -1,3 +1,19 @@
<!--
@license GNU AGPL version 3 or any later version
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template> <template>
<button class="side-menu-opener"></button> <button class="side-menu-opener"></button>
</template> </template>
+16
View File
@@ -1,3 +1,19 @@
<!--
@license GNU AGPL version 3 or any later version
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template> <template>
<div class="side-menu-settings"> <div class="side-menu-settings">
<a v-bind:href="href"> <a v-bind:href="href">
+14 -3
View File
@@ -25,8 +25,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<OpenerButton /> <OpenerButton />
<Logo v-if="!avatar && logo" v-bind:classes="{'side-menu-logo': true, 'avatardiv': false}" v-bind:image="logo" /> <Logo
<Logo v-if="avatar" v-bind:classes="{'side-menu-logo': true, 'avatardiv': true}" v-bind:image="avatar" /> v-if="!avatar && logo" v-bind:classes="{'side-menu-logo': true, 'avatardiv': false}"
v-bind:image="logo"
v-bind:link="logoLink"
/>
<Logo
v-if="avatar" v-bind:classes="{'side-menu-logo': true, 'avatardiv': true}"
v-bind:image="avatar"
v-bind:link="logoLink"
/>
</div> </div>
<ul class="side-menu-apps-list"> <ul class="side-menu-apps-list">
@@ -36,7 +45,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
v-bind:icon="app.icon" v-bind:icon="app.icon"
v-bind:label="app.name" v-bind:label="app.name"
v-bind:href="app.href" v-bind:href="app.href"
v-bind:target="targetBlankApps.indexOf(app.id) !== -1 ? '_blank' : undefined" v-bind:target="targetBlankApps.indexOf(appId) !== -1 ? '_blank' : undefined"
/> />
</ul> </ul>
</div> </div>
@@ -62,6 +71,7 @@ export default {
return { return {
apps: [], apps: [],
logo: null, logo: null,
logoLink: null,
avatar: null, avatar: null,
forceLightIcon: false, forceLightIcon: false,
targetBlankApps: [], targetBlankApps: [],
@@ -135,6 +145,7 @@ export default {
that.forceLightIcon = config['force-light-icon'] that.forceLightIcon = config['force-light-icon']
that.avatar = config['avatar'] that.avatar = config['avatar']
that.logo = config['logo'] that.logo = config['logo']
that.logoLink = config['logo-link']
that.settings = config['settings'] that.settings = config['settings']
}); });
}, },
+16
View File
@@ -1,3 +1,19 @@
<!--
@license GNU AGPL version 3 or any later version
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template> <template>
<li v-bind:class="classes"> <li v-bind:class="classes">
<a v-bind:href="href" :target="target" v-bind:title="label"> <a v-bind:href="href" :target="target" v-bind:title="label">
+1 -1
View File
@@ -43,7 +43,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
v-bind:icon="app.icon" v-bind:icon="app.icon"
v-bind:label="app.name" v-bind:label="app.name"
v-bind:href="app.href" v-bind:href="app.href"
v-bind:target="targetBlankApps.indexOf(app.id) !== -1 ? '_blank' : undefined" v-bind:target="targetBlankApps.indexOf(appId) !== -1 ? '_blank' : undefined"
/> />
</ul> </ul>
</div> </div>
+16
View File
@@ -1,3 +1,19 @@
<!--
@license GNU AGPL version 3 or any later version
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template> <template>
<li v-bind:class="classes"> <li v-bind:class="classes">
<a v-bind:href="href" :target="target" v-bind:title="label"> <a v-bind:href="href" :target="target" v-bind:title="label">
+16
View File
@@ -129,4 +129,20 @@ jQuery(document).ready(() => {
elementToggler(element) elementToggler(element)
}) })
jQuery("#categories-list .side-menu-setting-list").sortable({
forcePlaceholderSize: true,
placeholder: 'placeholder',
stop: function (event, ui) {
let value = []
jQuery('#categories-list .side-menu-setting-list-item').each(function() {
value.push(jQuery(this).attr('data-id'))
});
value = JSON.stringify(value)
jQuery('input[name="categories-order"]').val(value)
}
});
}); });
+12
View File
@@ -62,3 +62,15 @@
"Export the configuration": "Exportieren Sie die Konfiguration" "Export the configuration": "Exportieren Sie die Konfiguration"
"Purge the cache": "Leeren Sie den Cache" "Purge the cache": "Leeren Sie den Cache"
"Show the link to settings": "Zeigen Sie den Link zu den Einstellungen an" "Show the link to settings": "Zeigen Sie den Link zu den Einstellungen an"
"The menu is enabled by default for users": "Das Menü ist standardmäßig für Benutzer aktiviert"
"Except when the configuration is forced.": "Außer wenn die Konfiguration erzwungen wird."
"Apps that should not be displayed in the menu": "Apps, die nicht im Menü angezeigt werden sollen"
"This feature is only compatible with the <code>big menu</code> display.": "Kompatibel mit der Anzeige <code> Großes Menü </ code>."
"The logo is a link to the default app": "Das Logo ist ein Link zur Standard-App"
"Others": "Andere"
"Categories": "Kategorien"
"Customize sorting": "Sortierung anpassen"
"Order by": "Sortieren nach"
"Name": "Name"
"Customed": "Kundenspezifisch"
"Show and hide the list of categories": "Liste der Kategorien ein- und ausblenden"
+12
View File
@@ -62,3 +62,15 @@
"Export the configuration": "Exporter la configuration" "Export the configuration": "Exporter la configuration"
"Purge the cache": "Purger le cache" "Purge the cache": "Purger le cache"
"Show the link to settings": "Afficher le lien vers les paramètres" "Show the link to settings": "Afficher le lien vers les paramètres"
"The menu is enabled by default for users": "Le menu est activé par défaut pour les utilisateurs"
"Except when the configuration is forced.": "Sauf lorsque la configuration est forcée."
"Apps that should not be displayed in the menu": "Applications qui ne doivent pas être affichées dans le menu"
"This feature is only compatible with the <code>big menu</code> display.": "Compatible avec l'affichage <code>Menu large</code>."
"The logo is a link to the default app": "Le logo est un lien vers l'application par défaut"
"Others": "Autres"
"Categories": "Catégories"
"Customize sorting": "Personnaliser le tri"
"Order by": "Trier par"
"Name": "Nom"
"Customed": "Personnalisé"
"Show and hide the list of categories": "Afficher et masquer la liste des catégories"
+13 -7
View File
@@ -34,10 +34,14 @@ var alwaysDisplayed = function() {
for (var i in fixedElements) { for (var i in fixedElements) {
var element = fixedElements[i] var element = fixedElements[i]
var value = window.getComputedStyle(element, null).getPropertyValue('left') var computedStyle = window.getComputedStyle(element, null)
var intValue = parseInt(value.replace('px', '')) var left = computedStyle.getPropertyValue('left')
var right = computedStyle.getPropertyValue('right')
element.style.setProperty('transform', 'translateX(' + (intValue + 50) + 'px)') if (right !== '0px') {
var intValue = parseInt(left.replace('px', ''))
element.style.setProperty('transform', 'translateX(' + (intValue + 50) + 'px)')
}
} }
} }
@@ -45,14 +49,17 @@ let content = document.getElementById('content')
if (content && content.classList.contains('app-settings')) { if (content && content.classList.contains('app-settings')) {
let loaded = false let loaded = false
const config = {attributes: false, childList: true, subtree: true} const config = {
attributes: false,
childList: true,
subtree: true
}
const observer = new MutationObserver(() => { const observer = new MutationObserver(() => {
if (loaded) { if (loaded) {
return; return;
} }
const element = content.querySelector('#app-category-your-apps') const element = content.querySelector('#app-category-your-apps') || content.querySelector('#app-navigation ul')
|| content.querySelector('#app-navigation ul')
if (element) { if (element) {
loaded = true loaded = true
@@ -65,4 +72,3 @@ if (content && content.classList.contains('app-settings')) {
} else { } else {
window.setTimeout(alwaysDisplayed, 200) window.setTimeout(alwaysDisplayed, 200)
} }
+375 -249
View File
@@ -160,88 +160,83 @@ $choicesSizes = [
<?php p($l->t('Opener')); ?> <?php p($l->t('Opener')); ?>
</h2> </h2>
<?php <div class="side-menu-setting-table">
$choices = [ <?php
'Default' => 'side-menu-opener', $choices = [
'Default (dark)' => 'side-menu-opener-dark', 'Default' => 'side-menu-opener',
'Hamburger' => 'side-menu-opener-hamburger', 'Default (dark)' => 'side-menu-opener-dark',
'Hamburger (dark)' => 'side-menu-opener-hamburger-dark', 'Hamburger' => 'side-menu-opener-hamburger',
'Hamburger 2' => 'side-menu-opener-hamburger-2', 'Hamburger (dark)' => 'side-menu-opener-hamburger-dark',
'Hamburger 2 (dark)' => 'side-menu-opener-hamburger-2-dark', 'Hamburger 2' => 'side-menu-opener-hamburger-2',
]; 'Hamburger 2 (dark)' => 'side-menu-opener-hamburger-2-dark',
?> ];
?>
<div class="side-menu-setting-row">
<div class="side-menu-setting-label">
<?php p($l->t('Icon')); ?>
<small><span class="info"><?php p($l->t('Live preview')); ?></span></small>
</div>
<div class="side-menu-setting-form">
<select id="side-menu-opener" name="opener" class="side-menu-setting side-menu-setting-live">
<?php foreach ($choices as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div> <div class="side-menu-setting-row">
<label for="side-menu-opener"> <?php
<?php p($l->t('Icon')); ?> $choices = [
'Before the logo' => 'before',
'After the logo' => 'after',
];
?>
<div class="side-menu-setting-label">
<?php p($l->t('Position')); ?>
</div>
<div class="side-menu-setting-form">
<select id="side-menu-opener-position" name="opener-position" class="side-menu-setting">
<?php foreach ($choices as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener-position']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<small><span class="info"><?php p($l->t('Live preview')); ?></span></small> <div class="side-menu-setting-row">
</label> <div class="side-menu-setting-label">
</div> <?php p($l->t('Show only the opener (hidden logo)')); ?>
</div>
<div class="side-menu-setting-form">
<select id="side-menu-opener-only" name="opener-only" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener-only']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div> <div class="side-menu-setting-row">
<select id="side-menu-opener" name="opener" class="side-menu-setting side-menu-setting-live"> <div class="side-menu-setting-label">
<?php foreach ($choices as $label => $value): ?> <?php p($l->t('Do not display the side menu and the opener if there is no application (eg: public pages).')); ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener']): ?>selected<?php endif; ?>> </div>
<?php echo $l->t($label); ?> <div class="side-menu-setting-form">
</option> <select id="side-menu-hide-when-no-apps" name="hide-when-no-apps" class="side-menu-setting">
<?php endforeach; ?> <?php foreach ($choicesYesNo as $label => $value): ?>
</select> <option value="<?php echo $value ?>" <?php if ($value === $_['hide-when-no-apps']): ?>selected<?php endif; ?>>
</div> <?php echo $l->t($label); ?>
</option>
<?php <?php endforeach; ?>
$choices = [ </select>
'Before the logo' => 'before', </div>
'After the logo' => 'after', </div>
];
?>
<div>
<label for="side-menu-opener-position">
<?php p($l->t('Position')); ?>
</label>
</div>
<div>
<select id="side-menu-opener-position" name="opener-position" class="side-menu-setting">
<?php foreach ($choices as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener-position']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="side-menu-opener-only">
<?php p($l->t('Show only the opener (hidden logo)')); ?>
</label>
</div>
<div>
<select id="side-menu-opener-only" name="opener-only" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener-only']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="side-menu-hide-when-no-apps">
<?php p($l->t('Do not display the side menu and the opener if there is no application (eg: public pages).')); ?>
</label>
</div>
<div>
<select id="side-menu-hide-when-no-apps" name="hide-when-no-apps" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['hide-when-no-apps']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div> </div>
</div> </div>
@@ -288,8 +283,6 @@ $choicesSizes = [
src="<?php print_unescaped(image_path('side_menu', 'admin/layout-big-menu.svg')); ?>" alt="<?php p($l->t('Big menu')); ?>"> src="<?php print_unescaped(image_path('side_menu', 'admin/layout-big-menu.svg')); ?>" alt="<?php p($l->t('Big menu')); ?>">
</p> </p>
<br>
<div> <div>
<label for="side-menu-opener"> <label for="side-menu-opener">
<?php p($l->t('Always displayed')); ?> <?php p($l->t('Always displayed')); ?>
@@ -312,141 +305,193 @@ $choicesSizes = [
<br> <br>
<div>
<label for="side-menu-opener">
<?php p($l->t('Open the menu when the mouse is hover the opener (automatically disabled on touch screens)')); ?>
</label>
</div>
<p><em><?php p($l->t('This is the automatic behavior when the menu is always displayed.')); ?></em></p> <div class="side-menu-setting-table">
<div class="side-menu-setting-row">
<div class="side-menu-setting-label">
<?php p($l->t('Open the menu when the mouse is hover the opener (automatically disabled on touch screens)')); ?>
<div> <br>
<select id="side-menu-opener-hover" name="opener-hover" class="side-menu-setting"> <em><?php p($l->t('This is the automatic behavior when the menu is always displayed.')); ?></em>
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener-hover']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="side-menu-opener">
<?php p($l->t('Display the logo')); ?>
</label>
</div>
<p><em><?php echo $l->t('This feature is not compatible with the <code>big menu</code> display.'); ?></em></p>
<p><em><?php p($l->t('The logo will be hidden when the menu is always displayed.')); ?></em></p>
<div>
<select id="side-menu-display-logo" name="display-logo" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['display-logo']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<p><em><?php p($l->t('Use the avatar instead of the logo')); ?></em></p>
<div>
<select id="side-menu-use-avatar" name="use-avatar" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['use-avatar']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="side-menu-show-settings">
<?php p($l->t('Show the link to settings')); ?>
</label>
</div>
<div>
<select id="side-menu-show-settings" name="show-settings" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['show-settings']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label>
<?php p($l->t('Icons and texts')); ?>
</label>
</div>
<div>
<select id="side-menu-size-icon" name="size-icon" class="side-menu-setting">
<?php foreach ($choicesSizes as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['size-icon']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?> icon
</option>
<?php endforeach; ?>
</select>
<select id="side-menu-size-text" name="size-text" class="side-menu-setting">
<?php foreach ($choicesSizes as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['size-text']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?> text
</option>
<?php endforeach; ?>
</select>
</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> </div>
<?php endforeach; ?> <div class="side-menu-setting-form">
</div> <select id="side-menu-opener-hover" name="opener-hover" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener-hover']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<br> <div class="side-menu-setting-row">
<div class="side-menu-setting-label">
<?php p($l->t('Display the logo')); ?>
<br>
<em>
<?php echo $l->t('This feature is not compatible with the <code>big menu</code> display.'); ?>
<br>
<?php p($l->t('The logo will be hidden when the menu is always displayed.')); ?>
</em>
</div>
<div class="side-menu-setting-form">
<select id="side-menu-display-logo" name="display-logo" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['display-logo']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div> <div class="side-menu-setting-row">
<label for="side-menu-loader-enabled"> <div class="side-menu-setting-label">
<?php p($l->t('Loader enabled')); ?> <?php p($l->t('Use the avatar instead of the logo')); ?>
</label> </div>
</div> <div class="side-menu-setting-form">
<select id="side-menu-use-avatar" name="use-avatar" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['use-avatar']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div> <div class="side-menu-setting-row">
<select id="side-menu-loader-enabled" name="loader-enabled" class="side-menu-setting"> <div class="side-menu-setting-label">
<?php foreach ($choicesYesNo as $label => $value): ?> <?php p($l->t('The logo is a link to the default app')); ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['loader-enabled']): ?>selected<?php endif; ?>> </div>
<?php echo $l->t($label); ?> <div class="side-menu-setting-form">
</option> <select id="side-menu-add-logo-link" name="add-logo-link" class="side-menu-setting">
<?php endforeach; ?> <?php foreach ($choicesYesNo as $label => $value): ?>
</select> <option value="<?php echo $value ?>" <?php if ($value === $_['add-logo-link']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="side-menu-setting-row">
<div class="side-menu-setting-label">
<?php p($l->t('Apps that should not be displayed in the menu')); ?>
<br>
<em><?php echo $l->t('This feature is only compatible with the <code>big menu</code> display.'); ?></em>
</div>
<div class="side-menu-setting-form">
<a class="side-menu-toggler" data-target="#big-menu-hidden-apps" href="#_">
🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
</a>
<div class="side-menu-setting" data-name="big-menu-hidden-apps" id="big-menu-hidden-apps" data-checkbox style="display: none">
<ul class="side-menu-setting-list">
<?php foreach ($_['apps'] as $app): ?>
<li class="side-menu-setting-list-item">
<input
type="checkbox"
name="big-menu-hidden-apps[]"
value="<?php echo $app['id'] ?>"
id="big-menu-hidden-app-<?php echo $app['id'] ?>"
<?php if (in_array($app['id'], $_['big-menu-hidden-apps'])): ?>checked<?php endif; ?>
/>
<label for="big-menu-hidden-app-<?php echo $app['id'] ?>">
<?php echo p($l->t($app['name'])); ?>
</label>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
<div class="side-menu-setting-row">
<div class="side-menu-setting-label">
<?php p($l->t('Show the link to settings')); ?>
</div>
<div class="side-menu-setting-form">
<select id="side-menu-show-settings" name="show-settings" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['show-settings']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="side-menu-setting-row">
<div class="side-menu-setting-label">
<?php p($l->t('Icons and texts')); ?>
</div>
<div class="side-menu-setting-form">
<select id="side-menu-size-icon" name="size-icon" class="side-menu-setting">
<?php foreach ($choicesSizes as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['size-icon']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?> icon
</option>
<?php endforeach; ?>
</select>
<select id="side-menu-size-text" name="size-text" class="side-menu-setting">
<?php foreach ($choicesSizes as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['size-text']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?> text
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="side-menu-setting-row">
<div class="side-menu-setting-label">
<?php p($l->t('Open apps in new tab')); ?>
</div>
<div class="side-menu-setting-form">
<a class="side-menu-toggler" data-target="#target-blank-apps" href="#_">
🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
</a>
<div class="side-menu-setting" data-name="target-blank-apps" id="target-blank-apps" data-checkbox style="display: none">
<ul class="side-menu-setting-list">
<?php foreach ($_['apps'] as $app): ?>
<li class="side-menu-setting-list-item">
<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>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
<div class="side-menu-setting-row">
<div class="side-menu-setting-label">
<?php p($l->t('Loader enabled')); ?>
</div>
<div class="side-menu-setting-form">
<select id="side-menu-loader-enabled" name="loader-enabled" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['loader-enabled']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
</div> </div>
</div> </div>
@@ -454,34 +499,95 @@ $choicesSizes = [
<h2> <h2>
<?php p($l->t('Top menu')); ?> <?php p($l->t('Top menu')); ?>
</h2> </h2>
<div>
<label for="side-menu-top-menu-apps">
<?php p($l->t('Apps that not must be moved in the side menu')); ?>
</label>
</div>
<p> <div class="side-menu-setting-table">
<a class="side-menu-toggler" data-target="#top-menu-apps" href="#_"> <div class="side-menu-setting-row">
🖱️ <?php p($l->t('Show and hide the list of applications')); ?> <div class="side-menu-setting-label">
</a> <?php p($l->t('Apps that not must be moved in the side menu')); ?>
</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): ?>
<div>
<input
type="checkbox"
name="top-menu-apps[]"
value="<?php echo $app['id'] ?>"
id="top-menu-app-<?php echo $app['id'] ?>"
<?php if (in_array($app['id'], $_['top-menu-apps'])): ?>checked<?php endif; ?>
/>
<label for="top-menu-app-<?php echo $app['id'] ?>">
<?php echo p($l->t($app['name'])); ?>
</label>
</div> </div>
<?php endforeach; ?> <div class="side-menu-setting-form">
<a class="side-menu-toggler" data-target="#top-menu-apps" href="#_">
🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
</a>
<div class="side-menu-setting" data-name="top-menu-apps" id="top-menu-apps" data-checkbox style="display: none">
<ul class="side-menu-setting-list">
<?php foreach ($_['apps'] as $app): ?>
<li class="side-menu-setting-list-item">
<input
type="checkbox"
name="top-menu-apps[]"
value="<?php echo $app['id'] ?>"
id="top-menu-app-<?php echo $app['id'] ?>"
<?php if (in_array($app['id'], $_['top-menu-apps'])): ?>checked<?php endif; ?>
/>
<label for="top-menu-app-<?php echo $app['id'] ?>">
<?php echo p($l->t($app['name'])); ?>
</label>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="section">
<h2>
<?php p($l->t('Categories')); ?>
</h2>
<div class="side-menu-setting-table">
<div class="side-menu-setting-row">
<?php
$choices = [
'Name' => 'default',
'Customed' => 'custom',
];
?>
<div class="side-menu-setting-label">
<?php p($l->t('Order by')); ?>
</div>
<div class="side-menu-setting-form">
<select id="side-menu-categories-order-type" name="categories-order-type" class="side-menu-setting">
<?php foreach ($choices as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['categories-order-type']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="side-menu-setting-row">
<div class="side-menu-setting-label">
<?php p($l->t('Customize sorting')); ?>
</div>
<div class="side-menu-setting-form">
<a class="side-menu-toggler" data-target="#categories-list" href="#_">
🖱️ <?php p($l->t('Show and hide the list of categories')); ?>
</a>
<div class="side-menu-setting" data-name="categories" id="categories-list" style="display: none">
<ul class="side-menu-setting-list">
<?php foreach ($_['categories'] as $key => $label): ?>
<li data-id="<?php echo $key; ?>" class="side-menu-setting-list-item">
<span class="arrow">
⇅
</span>
<?php echo $label ? $l->t($label) : $l->t('Others'); ?>
</li>
<?php endforeach; ?>
</ul>
</div>
<input type="hidden" value='<?php echo json_encode(array_keys($_['categories'])) ?>' name="categories-order" class="side-menu-setting">
</div>
</div>
</div> </div>
</div> </div>
@@ -496,30 +602,50 @@ $choicesSizes = [
</div> </div>
<div class="section"> <div class="section">
<div> <div class="side-menu-setting-table">
<label for="side-menu-opener-only"> <div class="side-menu-setting-row">
<?php p($l->t('Force this configuration to users')); ?> <div class="side-menu-setting-label">
</label> <?php p($l->t('The menu is enabled by default for users')); ?>
<br>
<em><?php p($l->t('Except when the configuration is forced.')); ?></em>
</div>
<div class="side-menu-setting-form">
<select id="side-menu-default-enabled" name="default-enabled" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['default-enabled']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<select id="side-menu-force" name="force" class="side-menu-setting"> <div class="side-menu-setting-row">
<?php foreach ($choicesYesNo as $label => $value): ?> <div class="side-menu-setting-label">
<option value="<?php echo $value ?>" <?php if ($value === $_['force']): ?>selected<?php endif; ?>> <?php p($l->t('Force this configuration to users')); ?>
<?php echo $l->t($label); ?> </div>
</option> <div class="side-menu-setting-form">
<?php endforeach; ?> <select id="side-menu-force" name="force" class="side-menu-setting">
</select> <?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['force']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
</div> </div>
<input type="hidden" id="side-menu-cache" name="cache" value="<?php print_unescaped($_['cache']); ?>" class="side-menu-setting"> <input type="hidden" id="side-menu-cache" name="cache" value="<?php print_unescaped($_['cache']); ?>" class="side-menu-setting">
</div>
<div class="section" id="more">
<button id="side-menu-save" class="btn btn-info"> <button id="side-menu-save" class="btn btn-info">
<?php p($l->t('Save')); ?> <?php p($l->t('Save')); ?>
</button> </button>
<span id="side-menu-message" class="msg"></span> <span id="side-menu-message" class="msg"></span>
</div>
<div class="section" id="more">
<a href="<?php echo $urlGenerator->linkToRoute('side_menu.AdminSetting.exportConfiguration') ?>" target="_blank"> <a href="<?php echo $urlGenerator->linkToRoute('side_menu.AdminSetting.exportConfiguration') ?>" target="_blank">
<button class="btn btn-primary" > <button class="btn btn-primary" >
<?php p($l->t('Export the configuration')); ?> <?php p($l->t('Export the configuration')); ?>