From 30072500bcbdadeefb8c4bd7c901462af3786f86 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Tue, 11 Jan 2022 19:59:51 +0100 Subject: [PATCH] add a way to create custom categories and manage application categories --- css/admin.css | 2 +- lib/Service/AppRepository.php | 28 ++++- lib/Service/CategoryRepository.php | 24 +++- lib/Service/LangRepository.php | 43 +++++++ lib/Settings/Admin.php | 15 ++- package.json | 2 +- src/AdminCategoriesCustom.vue | 182 +++++++++++++++++++++++++++++ src/admin.js | 34 ++++++ src/l10n/fixtures/cs.yaml | 3 + src/l10n/fixtures/de.yaml | 2 + src/l10n/fixtures/fr.yaml | 2 + src/l10n/fixtures/zh_CN.yaml | 2 + templates/settings/admin-form.php | 54 +++++++++ 13 files changed, 386 insertions(+), 7 deletions(-) create mode 100644 lib/Service/LangRepository.php create mode 100644 src/AdminCategoriesCustom.vue diff --git a/css/admin.css b/css/admin.css index a15aa64..e9173ed 100644 --- a/css/admin.css +++ b/css/admin.css @@ -115,7 +115,7 @@ .side-menu-setting-form { display: table-cell; - width: 300px; + min-width: 300px; } .side-menu-setting-label-short { diff --git a/lib/Service/AppRepository.php b/lib/Service/AppRepository.php index 93c8f9c..d1ba8d8 100644 --- a/lib/Service/AppRepository.php +++ b/lib/Service/AppRepository.php @@ -21,10 +21,27 @@ class AppRepository */ protected $l10nFactory; - public function __construct(\OC_App $ocApp, IFactory $l10nFactory) + /** + * @var ConfigProxy + */ + protected $config; + + /** + * @var CategoryRepository + */ + protected $categoryRepository; + + public function __construct( + \OC_App $ocApp, + IFactory $l10nFactory, + ConfigProxy $config, + CategoryRepository $categoryRepository + ) { $this->ocApp = $ocApp; $this->l10nFactory = $l10nFactory; + $this->config = $config; + $this->categoryRepository = $categoryRepository; } /** @@ -35,6 +52,9 @@ class AppRepository public function getVisibleApps() { $navigation = $this->ocApp->getNavigation(); + $appCategoriesCustom = $this->config->getAppValueArray('apps-categories-custom', '[]'); + $categoriesCustom = $this->config->getAppValueArray('categories-custom', '[]'); + $categories = $this->categoryRepository->getOrderedCategories(); $apps = $this->ocApp->listAllApps(); $visibleApps = []; @@ -74,6 +94,12 @@ class AppRepository } } + foreach ($visibleApps as $id => $app) { + if (isset($appCategoriesCustom[$id]) && (isset($categoriesCustom[$id]) || isset($categories[$id]))) { + $visibleApps[$id]['category'] = [$appCategoriesCustom[$id]]; + } + } + usort($visibleApps, function ($a, $b) { return ($a['name'] < $b['name']) ? -1 : 1; }); diff --git a/lib/Service/CategoryRepository.php b/lib/Service/CategoryRepository.php index 3e67e63..7559854 100644 --- a/lib/Service/CategoryRepository.php +++ b/lib/Service/CategoryRepository.php @@ -5,6 +5,7 @@ namespace OCA\SideMenu\Service; use OC\App\AppStore\Fetcher\CategoryFetcher; use OCA\SideMenu\AppInfo\Application; use OCP\IConfig; +use OCP\IUserSession; use OCP\L10N\IFactory; /** @@ -34,16 +35,23 @@ class CategoryRepository */ protected $iConfig; + /** + * @var IUserSession + */ + protected $userSession; + public function __construct( CategoryFetcher $categoryFetcher, ConfigProxy $config, IConfig $iConfig, - IFactory $l10nFactory + IFactory $l10nFactory, + IUserSession $userSession ) { $this->categoryFetcher = $categoryFetcher; $this->l10nFactory = $l10nFactory; $this->config = $config; $this->iConfig = $iConfig; + $this->userSession = $userSession; } /** @@ -56,8 +64,8 @@ class CategoryRepository $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', '[]'); + $customCategories = $this->config->getAppValueArray('categories-custom', '[]'); if (empty($categoriesLabels)) { $categoriesLabels = $this->categoryFetcher->get(); @@ -74,6 +82,18 @@ class CategoryRepository $categoriesLabels['external_links'] = $this->l10nFactory->get('external')->t('External sites'); $categoriesLabels['other'] = ''; + $user = $this->userSession->getUser(); + + if ($user) { + $lang = $this->iConfig->getUserValue($user->getUid(), 'core', 'lang'); + } else { + $lang = 'en'; + } + + foreach ($customCategories as $category) { + $categoriesLabels[$category['id']] = $category[$lang] ?? $category['en']; + } + asort($categoriesLabels); if ('custom' === $type) { diff --git a/lib/Service/LangRepository.php b/lib/Service/LangRepository.php new file mode 100644 index 0000000..c998a7e --- /dev/null +++ b/lib/Service/LangRepository.php @@ -0,0 +1,43 @@ + + */ +class LangRepository +{ + /** + * @var IDBConnection + */ + protected $db; + + public function __construct(IDBConnection $db) + { + $this->db = $db; + } + + public function getUsedLangs(): array + { + $qb = $this->db->getQueryBuilder(); + + $qb->select($qb->createFunction('DISTINCT configvalue')) + ->where('configkey="lang" and appid="core" and configvalue<>"en"') + ->from('preferences') + ; + + $stmt = $qb->execute(); + + $langs = ['en']; + + foreach ($stmt->fetchAll() as $result) { + $langs[] = $result['configvalue']; + } + + return $langs; + } +} diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php index e7a2bab..0f6e390 100644 --- a/lib/Settings/Admin.php +++ b/lib/Settings/Admin.php @@ -28,6 +28,7 @@ use OCP\ILogger; use OCP\Settings\ISettings; use OCA\Theming\ThemingDefaults; use OCA\SideMenu\Service\Color; +use OCA\SideMenu\Service\LangRepository; class Admin implements ISettings { @@ -66,6 +67,11 @@ class Admin implements ISettings */ protected $color; + /** + * @var LangRepository + */ + protected $langRepository; + public function __construct( IL10N $l, ILogger $logger, @@ -73,7 +79,8 @@ class Admin implements ISettings AppRepository $appRepository, CategoryRepository $categoryRepository, ThemingDefaults $theming, - Color $color + Color $color, + LangRepository $langRepository ) { $this->l = $l; $this->logger = $logger; @@ -82,6 +89,7 @@ class Admin implements ISettings $this->categoryRepository = $categoryRepository; $this->theming = $theming; $this->color = $color; + $this->langRepository = $langRepository; } /** @@ -140,10 +148,13 @@ class Admin implements ISettings 'target-blank-apps' => $this->config->getAppValueArray('target-blank-apps', '[]'), 'top-menu-apps' => $this->config->getAppValueArray('top-menu-apps', '[]'), 'default-enabled' => $this->config->getAppValue('default-enabled', '1'), + 'apps' => $this->appRepository->getVisibleApps(), + 'apps-categories-custom' => $this->config->getAppValueArray('apps-categories-custom', '[]'), 'categories-order-type' => $this->config->getAppValue('categories-order-type', 'default'), 'categories-order' => $this->config->getAppValueArray('categories-order', '[]'), - 'apps' => $this->appRepository->getVisibleApps(), + 'categories-custom' => $this->config->getAppValueArray('categories-custom', '[]'), 'categories' => $this->categoryRepository->getOrderedCategories(), + 'langs' => $this->langRepository->getUsedLangs(), ]; return new TemplateResponse(Application::APP_ID, 'settings/admin-form', $parameters, ''); diff --git a/package.json b/package.json index e87767d..f38078f 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@nextcloud/axios": "^1.8.0", - "@nextcloud/vue": "^1.4.0", + "@nextcloud/vue": "^1.5.0", "axios": "^0.24.0", "trim": "0.0.1", "vue": "^2.6.11" diff --git a/src/AdminCategoriesCustom.vue b/src/AdminCategoriesCustom.vue new file mode 100644 index 0000000..909580d --- /dev/null +++ b/src/AdminCategoriesCustom.vue @@ -0,0 +1,182 @@ + + + + + + diff --git a/src/admin.js b/src/admin.js index 2d63eca..e2356e0 100644 --- a/src/admin.js +++ b/src/admin.js @@ -15,6 +15,12 @@ * along with this program. If not, see . */ +import AdminCategoriesCustom from './AdminCategoriesCustom.vue' +import Vue from 'vue' + +Vue.prototype.OC = window.OC +Vue.prototype.OCA = window.OCA + let elements = [] const selector = '#side-menu-message' @@ -108,7 +114,26 @@ const elementToggler = (element) => { element.style.display = display } +const updateAppsCategoriesCustom = () => { + let values = {} + + for (let item of document.querySelectorAll('.apps-categories-custom')) { + let app = item.getAttribute('data-app') + let value = item.value + + if (value) { + values[app] = value + } + } + + document.querySelector('#apps-categories-custom').value = JSON.stringify(values) +} + document.addEventListener('DOMContentLoaded', () => { + const View = Vue.extend(AdminCategoriesCustom) + const adminCategoriesCustom = new View({}) + adminCategoriesCustom.$mount('#side-menu-categories-custom') + elements = document.querySelectorAll('.side-menu-setting') document.querySelector('#side-menu-save').addEventListener('click', (event) => { @@ -134,6 +159,12 @@ document.addEventListener('DOMContentLoaded', () => { }) } + for (let item of document.querySelectorAll('.apps-categories-custom')) { + item.addEventListener('change', (event) => { + updateAppsCategoriesCustom() + }) + } + for (let item of document.querySelectorAll('.side-menu-setting-live')) { item.addEventListener('change', (event) => { const target = event.target @@ -196,9 +227,12 @@ document.addEventListener('DOMContentLoaded', () => { let value = [] for (let item of document.querySelectorAll('#categories-list .side-menu-setting-list-item')) { + console.log(item.getAttribute('data-id')) value.push(item.getAttribute('data-id')) } + console.log(value) + document.querySelector('input[name="categories-order"]').value = JSON.stringify(value) }) } catch (e) { diff --git a/src/l10n/fixtures/cs.yaml b/src/l10n/fixtures/cs.yaml index 215c0e3..d0b65ab 100644 --- a/src/l10n/fixtures/cs.yaml +++ b/src/l10n/fixtures/cs.yaml @@ -77,3 +77,6 @@ "This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "Tyto parametry jsou použity v případě, že je zapnutý (Breeze) tmavý motiv vzhledu." "Dark mode colors": "Barvy tmavého režimu" "With categories": "S kategoriemi" +"Custom categories": "Vlastní kategorie" +"Customize application categories": "Personnaliser les catégories des applications" +"Customize application categories": "Přizpůsobte kategorie aplikací" diff --git a/src/l10n/fixtures/de.yaml b/src/l10n/fixtures/de.yaml index 5d8353a..520e6d8 100644 --- a/src/l10n/fixtures/de.yaml +++ b/src/l10n/fixtures/de.yaml @@ -77,3 +77,5 @@ "This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "Diese Optionen werden auf Dark Theme oder Breeze Dark Theme angewendet." "Dark mode colors": "Farben für den dunklen Modus" "With categories": "Mit Kategorien" +"Custom categories": "Benutzerdefinierte Kategorien" +"Customize application categories": "Anwendungskategorien anpassen" diff --git a/src/l10n/fixtures/fr.yaml b/src/l10n/fixtures/fr.yaml index 56b286e..9cb2792 100644 --- a/src/l10n/fixtures/fr.yaml +++ b/src/l10n/fixtures/fr.yaml @@ -77,3 +77,5 @@ "This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "Ces paramètres sont utilisés lorsque le thème sombre ou le thème Breeze Dark sont activés." "Dark mode colors": "Couleurs du mode sombre" "With categories": "Avec les catégories" +"Custom categories": "Catégories personnalisées" +"Customize application categories": "Personnaliser les catégories des applications" diff --git a/src/l10n/fixtures/zh_CN.yaml b/src/l10n/fixtures/zh_CN.yaml index 969583d..5282c9f 100644 --- a/src/l10n/fixtures/zh_CN.yaml +++ b/src/l10n/fixtures/zh_CN.yaml @@ -77,3 +77,5 @@ "This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "此参数将应用于暗黑主题激活时。" "Dark mode colors": "暗黑模式颜色" "With categories": "有类别" +"Custom categories": "自定义类别" +"Customize application categories": "自定义应用程序类别" diff --git a/templates/settings/admin-form.php b/templates/settings/admin-form.php index 9b53d7d..00b5cc6 100644 --- a/templates/settings/admin-form.php +++ b/templates/settings/admin-form.php @@ -790,6 +790,60 @@ $choicesSizes = [ +
+
+ t('Custom categories')); ?> +
+
+ + +
+
+
+
+ +
+
+ t('Customize application categories')); ?> +
+
+ + 🖱️ t('Show and hide the list of applications')); ?> + + + + + +
+
+
t('Customize sorting')); ?>