From 8f86cbe188e2e4b549b3ba240832aa1466ec6380 Mon Sep 17 00:00:00 2001 From: deblan Date: Thu, 16 Mar 2023 06:11:24 +0000 Subject: [PATCH 001/228] Added translation using Weblate (Portuguese (Brazil)) --- src/l10n/fixtures/pt_BR.yaml | 93 ++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/l10n/fixtures/pt_BR.yaml diff --git a/src/l10n/fixtures/pt_BR.yaml b/src/l10n/fixtures/pt_BR.yaml new file mode 100644 index 0000000..102f41b --- /dev/null +++ b/src/l10n/fixtures/pt_BR.yaml @@ -0,0 +1,93 @@ +"Custom menu": "" +"Enable the custom menu": "" +"No": "" +"Yes": "" +"Menu": "" +? 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' +: '' +"Top menu": "" +"Apps that not must be moved in the side menu": "" +"If there is no selection then the global configuration is applied.": "" +"Experimental": "" +"Save": "" +"You like this app and you want to support me?": "" +"Buy me a coffee ☕": "" +"Hidden": "" +"Small": "" +"Normal": "" +"Big": "" +"Hidden icon": "" +"Small icon": "" +"Normal icon": "" +"Big icon": "" +"Hidden text": "" +"Small text": "" +"Normal text": "" +"Big text": "" +"Colors": "" +"Background color": "" +"Background color of current app": "" +"Text color": "" +"Loader": "" +"Icon": "" +"Same color": "" +"Opposite color": "" +"Transparent": "" +"Opaque": "" +"Opener": "" +"Default": "" +"Default (dark)": "" +"Hamburger": "" +"Hamburger (dark)": "" +"Hamburger 2": "" +"Hamburger 2 (dark)": "" +"Before the logo": "" +"After the logo": "" +"Position": "" +"Show only the opener (hidden logo)": "" +"Do not display the side menu and the opener if there is no application (eg: public pages).": "" +"Panel": "" +"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "" +"Display the big menu": "" +"Display the logo": "" +"Icons and texts": "" +"Loader enabled": "" +"Tips": "" +"Always displayed": "" +"This is the automatic behavior when the menu is always displayed.": "" +"Not compatible with touch screens.": "" +"Big menu": "" +"Live preview": "" +"Open apps in new tab": "" +"Use the global setting": "" +"Use my selection": "" +"Show and hide the list of applications": "" +"Use the avatar instead of the logo": "" +"You do not have permission to change the settings.": "" +"Force this configuration to users": "" +"Export the configuration": "" +"Purge the cache": "" +"Show the link to settings": "" +"The menu is enabled by default for users": "" +"Except when the configuration is forced.": "" +"Apps that should not be displayed in the menu": "" +"This feature is only compatible with the big menu display.": "" +"The logo is a link to the default app": "" +"Others": "" +"Categories": "" +"Customize sorting": "" +"Order by": "" +"Name": "" +"Customed": "" +"Show and hide the list of categories": "" +"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "" +"Dark mode colors": "" +"With categories": "" +"Custom categories": "" +"Customize application categories": "" +"Reset to default": "" +"Applications": "" +"Applications kept in the top menu": "" +"Applications kept in the top menu but also shown in side menu": "" +"These applications must be selected in the previous option.": "" +"Hide labels on mouse over": "" From 1e6d241e5cfbfffd633e48021f7a758e56d937e7 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Mon, 24 Jul 2023 21:32:13 +0200 Subject: [PATCH 002/228] release v3.10.3 --- CHANGELOG.md | 1 + appinfo/info.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca445c2..6cbaa46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## [Unreleased] +## 3.10.3 ### Fixed * change the way to load nextcloud components (NcActionLink/NcActions) - fix #274 * update @nexcloud/* packages diff --git a/appinfo/info.xml b/appinfo/info.xml index 106ee8b..9b358a2 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -32,7 +32,7 @@ Notice Because I believe in a free and decentralized Internet, [Gitnet](https://gitnet.fr) is **self-hosted at home**. In case of downtime, you can download **Custom Menu** from [here](https://kim.deblan.fr/~side_menu/). ]]> - 3.10.2 + 3.10.3 agpl Simon Vieille SideMenu From d6a8dee1b2ae8c4147aa1dd84475f5df13c52e1d Mon Sep 17 00:00:00 2001 From: mschmidm Date: Fri, 15 Sep 2023 08:03:18 +0000 Subject: [PATCH 003/228] Translated using Weblate (German) Currently translated at 100.0% (92 of 92 strings) Translation: Custom menu/Application Translate-URL: https://translate.codeberg.org/projects/custom-menu/application/de/ --- src/l10n/fixtures/de.yaml | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/l10n/fixtures/de.yaml b/src/l10n/fixtures/de.yaml index a8a2ed9..214377e 100644 --- a/src/l10n/fixtures/de.yaml +++ b/src/l10n/fixtures/de.yaml @@ -6,11 +6,11 @@ ? 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' : 'Verwende die Tastenkombination Strg+o, um das Seitenmenü ein- und auszublenden. Verwende tab zum Navigieren.' "Top menu": "Obere Navigationsleiste" -"Apps that not must be moved in the side menu": "Anwendungen, die nicht ins Seitenmenü verschoben werden sollen" +"Apps that not must be moved in the side menu": "Apps, die nicht ins Seitenmenü verschoben werden sollen" "If there is no selection then the global configuration is applied.": "Wenn keine Auswahl vorhanden ist, wird die globale Konfiguration angewendet." "Experimental": "Experimentell" "Save": "Speichern" -"You like this app and you want to support me?": "Du magst diese Anwendung und möchtest mich unterstützen?" +"You like this app and you want to support me?": "Du magst diese App und möchtest mich unterstützen?" "Buy me a coffee ☕": "Gib mir einen Kaffee aus ☕" "Hidden": "Ausblenden" "Small": "Klein" @@ -18,9 +18,9 @@ "Big": "Groß" "Colors": "Farben" "Background color": "Hintergrundfarbe" -"Background color of current app": "Hintergrundfarbe der aktuellen Anwendung" +"Background color of current app": "Hintergrundfarbe der aktuellen App" "Text color": "Textfarbe" -"Loader": "Ladestandanzeige" +"Loader": "Fortschrittsbalken" "Icon": "Symbol" "Same color": "Selbe Farbe" "Opposite color": "Gegenfarbe" @@ -37,32 +37,32 @@ "After the logo": "Nach dem Logo" "Position": "Position" "Show only the opener (hidden logo)": "Nur das Menü-Symbol anzeigen (Logo wird ausgeblendet)" -"Do not display the side menu and the opener if there is no application (eg: public pages).": "Zeige das Seitenmenü und das Menü-Symbol nicht an, wenn keine Anwendung vorhanden ist (z.B. bei öffentlichen Seiten)." +"Do not display the side menu and the opener if there is no application (eg: public pages).": "Zeige das Seitenmenü und das Menü-Symbol nicht an, wenn keine App vorhanden ist (z.B. bei öffentlichen Seiten)." "Panel": "Panel" "Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Öffne das Menü, wenn die Maus über das Menü-Symbol bewegt wird (auf Touchscreens automatisch deaktiviert)" "Display the big menu": "Großes Menü anzeigen" "Display the logo": "Logo anzeigen" "Icons and texts": "Symbole und Texte" -"Loader enabled": "Ladestandanzeige aktiviert" +"Loader enabled": "Fortschrittsbalken anzeigen" "Tips": "Tipps" "Always displayed": "Immer anzeigen" "This is the automatic behavior when the menu is always displayed.": "Dies ist das automatische Verhalten, wenn das Menü immer angezeigt wird." "Not compatible with touch screens.": "Nicht kompatibel mit Touchscreens." "Big menu": "Großes Menü" "Live preview": "Live-Vorschau" -"Open apps in new tab": "Öffne Anwendungen in einem neuen Tab" +"Open apps in new tab": "Öffne Apps in einem neuen Tab" "Use the global setting": "Verwende die globale Einstellung" "Use my selection": "Verwende meine Auswahl" -"Show and hide the list of applications": "Ein- und Ausblenden der Anwendungsliste" +"Show and hide the list of applications": "Ein- und Ausblenden der Appliste" "Use the avatar instead of the logo": "Avatar anstelle des Logos anzeigen" -"You do not have permission to change the settings.": "Du hast keine Berechtigung, die Einstellungen dieser Anwendung zu ändern." +"You do not have permission to change the settings.": "Du hast keine Berechtigung, die Einstellungen dieser App zu ändern." "Force this configuration to users": "Konfiguration für alle Benutzer erzwingen" "Export the configuration": "Konfiguration exportieren" "Purge the cache": "Cache leeren" "Show the link to settings": "Link zu den Einstellungen anzeigen" "The menu is enabled by default for users": "Das Menü ist standardmäßig für alle Benutzer aktiviert" "Except when the configuration is forced.": "Gilt nicht, wenn die Konfiguration erzwungen wird." -"Apps that should not be displayed in the menu": "Anwendungen, die nicht im Menü angezeigt werden sollen" +"Apps that should not be displayed in the menu": "Apps, die nicht im Menü angezeigt werden sollen" "This feature is only compatible with the big menu display.": "Kompatibel mit dem großen Menü." "The logo is a link to the default app": "Das Logo ist ein Link zur Standard-App" "Others": "Andere" @@ -76,18 +76,18 @@ "Dark mode colors": "Farben für den dunklen Modus" "With categories": "Mit Kategorien" "Custom categories": "Benutzerdefinierte Kategorien" -"Customize application categories": "Anwendungskategorien anpassen" +"Customize application categories": "App-Kategorien anpassen" "Reset to default": "Auf Standard zurücksetzen" "Hidden icon": "Verstecktes Symbol" "Small icon": "Kleines Symbol" "Normal icon": "Normales Symbol" -"Big icon": "Große Ikone" +"Big icon": "Großes Icon" "Hidden text": "Versteckter Text" "Small text": "Kleiner Text" "Normal text": "Normaler Text" "Big text": "Großer Text" -"Applications": "Anwendungen" -"Applications kept in the top menu": "Applications kept in the top menu" -"Applications kept in the top menu but also shown in side menu": "Applications kept in the top menu but also shown in side menu" -"These applications must be selected in the previous option.": "These applications must be selected in the previous option." -"Hide labels on mouse over": "Hide labels on mouse over" +"Applications": "Apps" +"Applications kept in the top menu": "Apps in der oberen Navigationsleiste" +"Applications kept in the top menu but also shown in side menu": "Apps in der oberen Navigationsleiste, die auch im Seitenmenü angezeigt werden sollen" +"These applications must be selected in the previous option.": "Diese Apps müssen auch in der vorherigen Einstellung ausgewählt werden." +"Hide labels on mouse over": "Labels ausblenden, wenn sich die Maus darüber befindet (Hover)" From 648bdeae04c323e7498a5f15281da88c85bfd500 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Fri, 29 Sep 2023 16:46:56 +0200 Subject: [PATCH 004/228] fix ci syntax --- .woodpecker.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 34f13eb..abe2b00 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -1,4 +1,4 @@ -pipeline: +steps: dependencies: image: node:16 pull: true @@ -6,7 +6,7 @@ pipeline: - npm i when: event: [tag, push, pull_request] - branch: [master, develop, feature/*, fix/*, translations] + branch: [master, develop, feature/*, fix/*, bugfix/*, translations] osv-detector: image: gitnet.fr/deblan/osv-detector:v0.10 @@ -19,7 +19,7 @@ pipeline: commands: - npm run build when: - branch: [master, develop, feature/*, fix/*, translations] + branch: [master, develop, feature/*, fix/*, bugfix/*, translations] event: [tag, push, pull_request] build-translations: @@ -27,7 +27,7 @@ pipeline: commands: - php bin/generate_l10n.php when: - branch: [master, develop, feature/*, fix/*, translations] + branch: [master, develop, feature/*, fix/*, bugfix/*, translations] event: [tag, push, pull_request] create-signature: From 3144f56b800863c94621b5b68f437bb7500d1e02 Mon Sep 17 00:00:00 2001 From: deblan Date: Mon, 16 Oct 2023 08:16:34 +0000 Subject: [PATCH 005/228] Added translation using Weblate (Slovak) --- src/l10n/fixtures/sk.yaml | 93 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/l10n/fixtures/sk.yaml diff --git a/src/l10n/fixtures/sk.yaml b/src/l10n/fixtures/sk.yaml new file mode 100644 index 0000000..102f41b --- /dev/null +++ b/src/l10n/fixtures/sk.yaml @@ -0,0 +1,93 @@ +"Custom menu": "" +"Enable the custom menu": "" +"No": "" +"Yes": "" +"Menu": "" +? 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' +: '' +"Top menu": "" +"Apps that not must be moved in the side menu": "" +"If there is no selection then the global configuration is applied.": "" +"Experimental": "" +"Save": "" +"You like this app and you want to support me?": "" +"Buy me a coffee ☕": "" +"Hidden": "" +"Small": "" +"Normal": "" +"Big": "" +"Hidden icon": "" +"Small icon": "" +"Normal icon": "" +"Big icon": "" +"Hidden text": "" +"Small text": "" +"Normal text": "" +"Big text": "" +"Colors": "" +"Background color": "" +"Background color of current app": "" +"Text color": "" +"Loader": "" +"Icon": "" +"Same color": "" +"Opposite color": "" +"Transparent": "" +"Opaque": "" +"Opener": "" +"Default": "" +"Default (dark)": "" +"Hamburger": "" +"Hamburger (dark)": "" +"Hamburger 2": "" +"Hamburger 2 (dark)": "" +"Before the logo": "" +"After the logo": "" +"Position": "" +"Show only the opener (hidden logo)": "" +"Do not display the side menu and the opener if there is no application (eg: public pages).": "" +"Panel": "" +"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "" +"Display the big menu": "" +"Display the logo": "" +"Icons and texts": "" +"Loader enabled": "" +"Tips": "" +"Always displayed": "" +"This is the automatic behavior when the menu is always displayed.": "" +"Not compatible with touch screens.": "" +"Big menu": "" +"Live preview": "" +"Open apps in new tab": "" +"Use the global setting": "" +"Use my selection": "" +"Show and hide the list of applications": "" +"Use the avatar instead of the logo": "" +"You do not have permission to change the settings.": "" +"Force this configuration to users": "" +"Export the configuration": "" +"Purge the cache": "" +"Show the link to settings": "" +"The menu is enabled by default for users": "" +"Except when the configuration is forced.": "" +"Apps that should not be displayed in the menu": "" +"This feature is only compatible with the big menu display.": "" +"The logo is a link to the default app": "" +"Others": "" +"Categories": "" +"Customize sorting": "" +"Order by": "" +"Name": "" +"Customed": "" +"Show and hide the list of categories": "" +"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "" +"Dark mode colors": "" +"With categories": "" +"Custom categories": "" +"Customize application categories": "" +"Reset to default": "" +"Applications": "" +"Applications kept in the top menu": "" +"Applications kept in the top menu but also shown in side menu": "" +"These applications must be selected in the previous option.": "" +"Hide labels on mouse over": "" From 9a3573465739965e4c2f1e5441155711c152dd96 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Sat, 4 Nov 2023 13:33:34 +0100 Subject: [PATCH 006/228] remove label of the link to personal settings (fix #283) --- css/sideMenu.css | 6 +++--- src/SettingsButton.vue | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/css/sideMenu.css b/css/sideMenu.css index 7fc71a2..6b2c5e2 100644 --- a/css/sideMenu.css +++ b/css/sideMenu.css @@ -47,7 +47,7 @@ margin-top: 2px; float: right; line-height: 34px; - height: 28px; + height: 42px; display: none; } @@ -155,7 +155,7 @@ } #side-menu.hide-opener .side-menu-logo { - margin-top: 20px; + margin-top: 10px; } #side-menu-loader { @@ -223,7 +223,7 @@ } .side-menu-loader svg { - width: 38px; + width: 45px; margin: auto; stroke: var(--side-menu-text-color, #fff); } diff --git a/src/SettingsButton.vue b/src/SettingsButton.vue index a4eb97f..b8cb624 100644 --- a/src/SettingsButton.vue +++ b/src/SettingsButton.vue @@ -17,7 +17,9 @@ along with this program. If not, see . diff --git a/src/lib/dom.js b/src/lib/dom.js index 99081f7..f1e6913 100644 --- a/src/lib/dom.js +++ b/src/lib/dom.js @@ -1,11 +1,13 @@ const waitContainer = async (selector) => { - new Promise((resolve) => { - setTimeout(() => { - const container = document.querySelector(selector) + return new Promise((resolve) => { + const container = document.querySelector(selector) - if (container) { - resolve(selector, container) - } + if (container) { + return resolve(selector, container) + } + + setTimeout(() => { + waitContainer(selector) }, 50) }) } diff --git a/src/lib/search.js b/src/lib/search.js index fed40d2..4fee589 100644 --- a/src/lib/search.js +++ b/src/lib/search.js @@ -13,14 +13,11 @@ const containsAppsMatchingSearch = (values, search) => { } const isAppMatchingSearch = (item, search) => { - if (search.value.trim() === '') { + if (search.trim() === '') { return true } - return item.name.toLowerCase().includes(search.value.trim().toLowerCase()) + return item.name.toLowerCase().includes(search.trim().toLowerCase()) } -export { - containsAppsMatchingSearch, - isAppMatchingSearch, -} +export { containsAppsMatchingSearch, isAppMatchingSearch } diff --git a/src/menu.js b/src/menu.js index c3dd834..b9842c0 100644 --- a/src/menu.js +++ b/src/menu.js @@ -19,39 +19,29 @@ import './scss/menu.scss' import { createApp } from 'vue' import { createPinia } from 'pinia' -import { waitContainer } from './lib/dom.js' +import { createElement } from './lib/dom.js' -// import AppMenu from './menus/AppMenu.vue' -import SideMenu from './menus/SideMenu.vue' -import SideMenuBig from './menus/SideMenuBig.vue' -import SideMenuWithCategories from './menus/SideMenuWithCategories.vue' +import MenuContainer from './menus/MenuContainer.vue' // import PageLoader from './components/PageLoader.vue' - // window.PageLoader = PageLoader const pinia = createPinia() - -waitContainer('#side-menu').then((selector, container) => { - const component = (() => { - if (container.getAttribute('data-bigmenu')) { - return SideMenuBig - } else if (container.getAttribute('data-sidewithcategories')) { - return SideMenuWithCategories - } else { - return SideMenu - } - })() - - const app = createApp(component) - - app.use(pinia) - app.mount(selector) +const body = document.querySelector('body') +const container = createElement('div', { + id: 'side-menu-container', }) -waitContainer('#header .app-menu').then((selector) => { - const app = createApp(AppMenu) +body.appendChild(container) - app.use(pinia) - app.mount(selector) -}) +const app = createApp(MenuContainer) +app.use(pinia) +app.mixin({ methods: { t, n }}) +app.mount(container) + +// waitContainer('#header .app-menu').then((selector) => { +// const app = createApp(AppMenu) +// app.use(pinia) +// app.mixin({ methods: { t, n }}) +// app.mount(selector) +// }) diff --git a/src/menus/MenuContainer.vue b/src/menus/MenuContainer.vue new file mode 100644 index 0000000..1a3137c --- /dev/null +++ b/src/menus/MenuContainer.vue @@ -0,0 +1,87 @@ + + + diff --git a/src/menus/SideMenu.vue b/src/menus/SimpleSideMenu.vue similarity index 92% rename from src/menus/SideMenu.vue rename to src/menus/SimpleSideMenu.vue index 7b9522e..cfe0ee1 100644 --- a/src/menus/SideMenu.vue +++ b/src/menus/SimpleSideMenu.vue @@ -17,8 +17,8 @@ along with this program. If not, see . diff --git a/src/components/CloserButton.vue b/src/components/CloserButton.vue index bcee43f..efcb225 100644 --- a/src/components/CloserButton.vue +++ b/src/components/CloserButton.vue @@ -17,8 +17,13 @@ along with this program. If not, see . + + diff --git a/src/components/OpenerButton.vue b/src/components/OpenerButton.vue index 08cbcff..282b2d9 100644 --- a/src/components/OpenerButton.vue +++ b/src/components/OpenerButton.vue @@ -18,7 +18,12 @@ along with this program. If not, see . + + diff --git a/src/components/PageLoader.vue b/src/components/PageLoader.vue index 95ded5e..2c67902 100644 --- a/src/components/PageLoader.vue +++ b/src/components/PageLoader.vue @@ -1,6 +1,9 @@ diff --git a/src/lib/search.js b/src/lib/search.js index 4fee589..2e4f409 100644 --- a/src/lib/search.js +++ b/src/lib/search.js @@ -1,10 +1,10 @@ const containsAppsMatchingSearch = (values, search) => { - if (search.value.trim() === '') { + if (search.trim() === '') { return true } for (let key in values) { - if (isAppMatchingSearch(values[key].name)) { + if (isAppMatchingSearch(values[key], search)) { return true } } diff --git a/src/menu.js b/src/menu.js index b9842c0..99ab101 100644 --- a/src/menu.js +++ b/src/menu.js @@ -36,7 +36,7 @@ body.appendChild(container) const app = createApp(MenuContainer) app.use(pinia) -app.mixin({ methods: { t, n }}) +app.mixin({ methods: { t, n } }) app.mount(container) // waitContainer('#header .app-menu').then((selector) => { diff --git a/src/menus/MenuContainer.vue b/src/menus/MenuContainer.vue index 1a3137c..69d7acf 100644 --- a/src/menus/MenuContainer.vue +++ b/src/menus/MenuContainer.vue @@ -1,11 +1,22 @@ diff --git a/src/menus/SimpleSideMenu.vue b/src/menus/SimpleSideMenu.vue index cfe0ee1..2b36b0b 100644 --- a/src/menus/SimpleSideMenu.vue +++ b/src/menus/SimpleSideMenu.vue @@ -15,19 +15,26 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> diff --git a/src/menus/TopWideMenu.vue b/src/menus/TopWideMenu.vue index 41044a3..46a3682 100644 --- a/src/menus/TopWideMenu.vue +++ b/src/menus/TopWideMenu.vue @@ -18,17 +18,25 @@ along with this program. If not, see .
- + - - + +
@@ -56,7 +64,7 @@ along with this program. If not, see . :key="appId" > . diff --git a/src/scss/menu.scss b/src/scss/menu.scss index c1be903..9e8c749 100644 --- a/src/scss/menu.scss +++ b/src/scss/menu.scss @@ -29,19 +29,25 @@ rgba(0, 0, 0, 0.22) 0px 25.6px 57.6px 0px, rgba(0, 0, 0, 0.18) 0px 4.8px 14.4px 0px; display: none; + + a { + transition: 0.2s; + } + + &.open { + display: block; + + .side-menu-settings { + display: block; + } + } } -#side-menu a { - transition: 0.2s; -} - -#side-menu.open { - display: block; -} - -#header .side-menu-opener { - margin-left: 0px; - margin-top: -1px; +#header { + .side-menu-opener { + margin-left: 0px; + margin-top: -1px; + } } .side-menu-settings { @@ -51,29 +57,25 @@ line-height: 34px; height: 42px; display: none; -} -.side-menu-settings a { - color: var(--side-menu-text-color, #fff); - display: block; - padding: 4px 7px; -} + a { + color: var(--side-menu-text-color, #fff); + display: block; + padding: 4px 7px; + } -.side-menu-settings:hover a, -.side-menu-settings a:active, -.side-menu-settings a:focus { - background: var(--side-menu-current-app-background-color, #444); -} + &:hover a, + a:active, + a:focus { + background: var(--side-menu-current-app-background-color, #444); + } -.side-menu-settings img { - vertical-align: bottom; - margin-left: 3px; - width: 32px; - height: 32px; -} - -#side-menu.open .side-menu-settings { - display: block; + img { + vertical-align: bottom; + margin-left: 3px; + width: 32px; + height: 32px; + } } .side-menu-opener { @@ -88,20 +90,20 @@ margin-left: 5px !important; margin-left: 3px !important; overflow: hidden; -} -.side-menu-opener span { - position: relative; - left: 50px; - display: block; - width: 1px; - height: 1px; - overflow: hidden; -} + span { + position: relative; + left: 50px; + display: block; + width: 1px; + height: 1px; + overflow: hidden; + } -.side-menu-opener:active, -.side-menu-opener:focus { - background-color: var(--side-menu-current-app-background-color, #444) !important; + &:active, + &:focus { + background-color: var(--side-menu-current-app-background-color, #444) !important; + } } .side-menu-closer { @@ -134,39 +136,47 @@ opacity: var(--side-menu-icon-opacity, 1); } -.side-menu-app a { - line-height: 30px; - color: var(--side-menu-text-color, #fff); - display: block; - padding: 7px 0 5px 15px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} +.side-menu-app { + a { + line-height: 30px; + color: var(--side-menu-text-color, #fff); + display: block; + padding: 7px 0 5px 15px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } -.side-menu-app a:hover, -.side-menu-app.active, -.side-menu-app a:focus { - background: var(--side-menu-current-app-background-color, #444); + a:hover, + a:focus, + &:active { + background: var(--side-menu-current-app-background-color, #444); + } } .side-menu-logo { text-align: center; + clear: both; + + img { + max-width: 60%; + max-height: 100px; + } } -.side-menu-logo img { - max-width: 60%; - max-height: 100px; -} - -.enu-header { +.side-menu-header { height: 150px; width: 100%; z-index: 2300; max-width: 290px; - position: fixed; padding-top: 2px; top: 0; + + &::after { + content: ' '; + display: block; + clear: both; + } } #side-menu.side-menu-with-categories .side-menu-header { @@ -183,13 +193,13 @@ left: 0; width: 100%; z-index: 3001; -} -#side-menu-loader-bar { - height: 4px; - background: var(--side-menu-loader-color, #0e75ac); - width: 0; - transition-property: width; + #side-menu-loader-bar { + height: 4px; + background: var(--side-menu-loader-color, #0e75ac); + width: 0; + transition-property: width; + } } #side-menu.side-menu-big, @@ -261,64 +271,75 @@ margin-top: -2px; } -.side-menu-always-displayed body { - width: calc(100% - 50px) !important; - position: absolute; - left: 50px; -} +.side-menu-always-displayed { + body { + width: calc(100% - 50px) !important; + position: absolute; + left: 50px; + } -.side-menu-always-displayed #header { - position: absolute !important; -} + #header { + position: absolute !important; + } -.side-menu-always-displayed #side-menu { - display: block; -} + #side-menu { + display: block; + } -.side-menu-always-displayed .side-menu-apps-list { - height: 100vh; - top: 0; - overflow: hidden; -} + .side-menu-apps-list { + height: 100vh; + top: 0; + overflow: hidden; + } -.side-menu-always-displayed .side-menu-apps-list--with-settings { - height: calc(100vh - 49px); - top: 49px; -} + .side-menu-apps-list--with-settings { + height: calc(100vh - 49px); + top: 49px; + } -.side-menu-always-displayed .side-menu-apps-list:hover { - overflow: auto; -} + .side-menu-apps-list:hover { + overflow: auto; + } -.side-menu-always-displayed #side-menu, -.side-menu-always-displayed .side-menu-header, -.side-menu-always-displayed .side-menu-apps-list { - width: 50px; -} + #side-menu, + .side-menu-header, + .side-menu-apps-list { + width: 50px; + } -.side-menu-always-displayed #side-menu .side-menu-app-text, -.side-menu-always-displayed #header .side-menu-opener, -.side-menu-always-displayed .side-menu-logo { - display: none; -} + #side-menu .side-menu-app-text, + #header .side-menu-opener, + .side-menu-logo { + display: none; + } -.side-menu-always-displayed #side-menu .side-menu-header { - height: 49px; -} + #side-menu .side-menu-header { + height: 49px; + } -.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-header { - width: 100%; -} + #side-menu.open, + #side-menu.open .side-menu-apps-list, + #side-menu.open .side-menu-header { + width: 100%; + } -.side-menu-always-displayed #side-menu.open .side-menu-app-text { - display: inline; -} + #side-menu.open .side-menu-app-text { + display: inline; + } -.side-menu-always-displayed .app-navigation-toggle-wrapper { - right: 0 !important; - margin-left: 0 !important; + .app-navigation-toggle-wrapper { + right: 0 !important; + margin-left: 0 !important; + } + + .side-menu-search { + display: none; + } + + #body-settings, + #body-settings.body-settings-side-menu { + overflow-x: visible; + } } #side-menu.side-menu-with-categories { @@ -326,19 +347,16 @@ height: 100vh; } -.side-menu-with-categories .side-menu-categories { - display: block; - padding: 0; - width: 100%; -} +.side-menu-with-categories { + .side-menu-categories { + display: block; + padding: 0; + width: 100%; + } -.side-menu-with-categories .side-menu-category { - padding: 10px 0; -} - -.side-menu-always-displayed #body-settings, -#body-settings.body-settings-side-menu { - overflow-x: visible; + .side-menu-category { + padding: 10px 0; + } } .app-menu { @@ -353,19 +371,17 @@ float: right; } -.side-menu-search input { - background: none; - border: 0; - border-radius: 0; - color: var(--side-menu-text-color); -} +.side-menu-search { + input { + background: none; + border: 0; + border-radius: 0; + color: var(--side-menu-text-color); -.side-menu-search input::placeholder { - color: var(--side-menu-text-color); -} - -.side-menu-always-displayed .side-menu-search { - display: none; + &::placeholder { + color: var(--side-menu-text-color); + } + } } @media screen and (max-width: 1024px) { diff --git a/templates/js/script.php b/templates/js/script.php index 406c672..6550507 100644 --- a/templates/js/script.php +++ b/templates/js/script.php @@ -1,65 +1,12 @@ - -const SMcreateElement = (tagName, attributes) => { - const element = document.createElement(tagName) - - if (typeof attributes === 'object') { - for (let i in attributes) { - if (i === 'text') { - element.textContent = attributes[i] - } else if (i === 'html') { - element.innerHTML = attributes[i] - } else { - element.setAttribute(i, attributes[i]) - } - } - } - - return element -} - (function() { - const sideMenuContainer = SMcreateElement('div', {id: 'side-menu-container'}) - const sideMenuOpener = SMcreateElement('button', { - 'class': 'side-menu-opener', - 'arial-label': t('side_menu', 'Toggle the menu'), - 'html': `${t('side_menu', 'Toggle the menu')}` - }) - const sideMenu = SMcreateElement('div', {id: 'side-menu'}) - const body = document.querySelector('body') const html = document.querySelector('html') const nextcloud = document.querySelector('#nextcloud') const logo = document.querySelector('.header-left .logo') - const isTouchDevice = window.matchMedia("(pointer: coarse)").matches - window.targetBlankApps = - window.topMenuApps = - window.topSideMenuApps = - window.menuAppsOrder = - window.topMenuAppsMouseOverHiddenLabel = - - - sideMenu.setAttribute('data-bigmenu', '1') - - sideMenu.setAttribute('data-sidewithcategories', '1') - - const sideMenuFocus = () => { let a = document.querySelector('#side-menu .side-menu-app.active a') || document.querySelector('#side-menu .side-menu-app a') @@ -71,101 +18,11 @@ const SMcreateElement = (tagName, attributes) => { document.querySelector('body').addEventListener('side-menu.apps', (e) => { const apps = e.detail.apps; - - - const sideMenu = document.querySelector('#side-menu') - - if (apps.length === 0) { - sideMenu.classList.remove('open') - sideMenu.classList.add('hide') - sideMenuOpener.classList.add('hide') - } else { - sideMenu.classList.remove('hide') - sideMenuOpener.classList.remove('hide') - } - - - if (apps.length === 0) { - html.classList.remove('side-menu-always-displayed') - } else { - html.classList.add('side-menu-always-displayed') - } - - - - if (apps.length === 0) { - html.classList.remove('side-menu-always-displayed') - } else { - html.classList.add('side-menu-always-displayed') - } - - }) body.addEventListener('side-menu.ready', () => { const sideMenu = document.querySelector('#side-menu') - const headerMenuOpener = document.querySelector('#header .side-menu-opener') - const sideMenuOpener = document.querySelectorAll('#side-menu .side-menu-opener') - if (!headerMenuOpener) { - return - } - - - const sideMenuMouseLeave = () => { - sideMenu.classList.remove('open') - sideMenu.removeEventListener('mouseleave', sideMenuMouseLeave) - } - - const sideMenuMouseEnter = () => { - sideMenu.addEventListener('mouseleave', sideMenuMouseLeave) - } - - const sideMenuOpenerMouseEnter = () => { - sideMenu.classList.add('open') - sideMenu.addEventListener('mouseenter', sideMenuMouseEnter) - - sideMenuFocus() - } - - if (!isTouchDevice) { - - headerMenuOpener.addEventListener('mouseenter', sideMenuOpenerMouseEnter) - - sideMenu.classList.add('hide-opener') - - - sideMenu.addEventListener('mouseleave', sideMenuMouseLeave) - sideMenu.addEventListener('mouseenter', sideMenuOpenerMouseEnter) - } - - - headerMenuOpener.addEventListener('click', () => { - sideMenu.classList.add('open') - headerMenuOpener.blur() - sideMenuFocus() - }) - - for (let opener of sideMenuOpener) { - opener.addEventListener('click', () => { - - sideMenu.classList.toggle('open') - - sideMenu.classList.remove('open') - - }) - } - - document.addEventListener('keydown', (e) => { - var key = e.key || e.keyCode - - if ((key === 'o' || key === 79) && e.ctrlKey === true) { - e.preventDefault() - - sideMenu.classList.toggle('open') - sideMenuFocus() - } - }) const sideMenuObserver = new MutationObserver((e) => { if (body.getAttribute('id') !== 'body-settings') { @@ -182,23 +39,4 @@ const SMcreateElement = (tagName, attributes) => { characterData: false }) }) - - body.appendChild(sideMenuContainer) - sideMenuContainer.appendChild(sideMenu) - - - // PageLoader() - - - if (nextcloud) { - if (logo && logo.parentNode !== nextcloud) { - nextcloud.appendChild(logo) - } - - - nextcloud.parentNode.insertBefore(sideMenuOpener, nextcloud) - - nextcloud.parentNode.insertBefore(sideMenuOpener, nextcloud.nextSibling) - - } })(); From 52b2d18a03f36f759c4e9477c33a841abb781726 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Wed, 9 Apr 2025 19:15:43 +0200 Subject: [PATCH 120/228] refactor of menus begin work on settings --- lib/AppInfo/Application.php | 16 +- lib/Controller/JsController.php | 2 + lib/Controller/NavController.php | 1 + package.json | 2 + src/admin.js | 269 +---- src/components/AdminCategoriesCustom.vue | 175 ++- src/components/settings/MenuDisplay.vue | 33 + src/components/settings/TableContainer.vue | 5 + src/components/settings/TableLabel.vue | 33 + src/components/settings/TableRow.vue | 5 + src/components/settings/TableValue.vue | 15 + src/lib/app.js | 2 +- src/lib/menu.js | 12 + src/menus/MenuContainer.vue | 6 + src/menus/SideMenuWithCategories.vue | 9 +- src/menus/SimpleSideMenu.vue | 41 +- src/menus/TopWideMenu.vue | 9 +- src/pages/AdminSettings.vue | 104 ++ src/scss/admin.scss | 25 + src/scss/menu.scss | 130 +-- templates/css/stylesheet.php | 63 +- templates/js/script.php | 42 - templates/settings/admin-form.php | 1127 +------------------ templates/settings/admin-form.php.bk | 1148 ++++++++++++++++++++ webpack.config.js | 2 +- webpack.rules.js | 4 + 26 files changed, 1613 insertions(+), 1667 deletions(-) create mode 100644 src/components/settings/MenuDisplay.vue create mode 100644 src/components/settings/TableContainer.vue create mode 100644 src/components/settings/TableLabel.vue create mode 100644 src/components/settings/TableRow.vue create mode 100644 src/components/settings/TableValue.vue create mode 100644 src/lib/menu.js create mode 100644 src/pages/AdminSettings.vue delete mode 100644 templates/js/script.php create mode 100644 templates/settings/admin-form.php.bk diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 42afdfc..0b9fd24 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -123,14 +123,14 @@ class Application extends App implements IBootstrap //Util::addStyle(self::APP_ID, 'sideMenu'); $assets = [ - // 'stylesheet' => [ - // 'route' => 'side_menu.Css.stylesheet', - // 'type' => 'link', - // 'route_attr' => 'href', - // 'attr' => [ - // 'rel' => 'stylesheet', - // ], - // ], + 'stylesheet' => [ + 'route' => 'side_menu.Css.stylesheet', + 'type' => 'link', + 'route_attr' => 'href', + 'attr' => [ + 'rel' => 'stylesheet', + ], + ], // 'script' => [ // 'route' => 'side_menu.Js.script', // 'type' => 'script', diff --git a/lib/Controller/JsController.php b/lib/Controller/JsController.php index 8f06345..68cf330 100644 --- a/lib/Controller/JsController.php +++ b/lib/Controller/JsController.php @@ -145,6 +145,8 @@ class JsController extends Controller 'opener-hover' => $this->config->getAppValueBool('opener-hover', '0'), 'external-sites-in-top-menu' => $this->config->getAppValueBool('external-sites-in-top-menu', '0'), 'force-light-icon' => $this->config->getAppValueBool('force-light-icon', '0'), + 'display-logo' => $this->config->getAppValueBool('display-logo', '1'), + 'use-avatar' => $this->config->getAppValueBool('use-avatar', '0'), 'hide-when-no-apps' => $this->config->getAppValueBool('hide-when-no-apps', '0'), 'loader-enabled' => $this->config->getAppValueBool('loader-enabled', '1'), 'always-displayed' => $this->config->getAppValueBool('always-displayed', '0'), diff --git a/lib/Controller/NavController.php b/lib/Controller/NavController.php index 1d90849..e2bdef4 100644 --- a/lib/Controller/NavController.php +++ b/lib/Controller/NavController.php @@ -115,6 +115,7 @@ class NavController extends Controller $appsCategories[$app['id']][] = $category; $items[$category]['apps'][$app['id']] = [ + 'id' => $app['id'], 'name' => $app['name'], 'href' => $app['href'], 'icon' => $app['icon'], diff --git a/package.json b/package.json index fb48ac4..c34ca5e 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,12 @@ "format": "./node_modules/.bin/prettier src --write" }, "dependencies": { + "@babel/core": ">=7.12.0 <8.0.0", "@nextcloud/router": "^3.0.1", "@nextcloud/vue": "^9.0.0-alpha.8", "node-polyfill-webpack-plugin": "^4.1.0", "pinia": "^3.0.1", + "postcss": "^7.0.0 || ^8.0.1", "vue": "^3.5.13" }, "browserslist": [ diff --git a/src/admin.js b/src/admin.js index d79ea98..cf5e607 100644 --- a/src/admin.js +++ b/src/admin.js @@ -8,268 +8,25 @@ * * 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 + * 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 . + * along with this program. If not, see . */ +import './scss/admin.scss' + import { createApp } from 'vue' -import AdminCategoriesCustom from './components/AdminCategoriesCustom.vue' +import { createPinia } from 'pinia' +import { waitContainer } from './lib/dom.js' -let elements = [] +import AdminSettings from './pages/AdminSettings.vue' -const selector = '#side-menu-message' - -const userConfig = (name, value, callbacks) => { - const url = OC.generateUrl('/apps/side_menu/personalSetting/valueSet') - const formData = [] - - formData.push('name=' + encodeURIComponent(name)) - formData.push('value=' + encodeURIComponent(value)) - - fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - body: formData.join('&'), - }) - .then(callbacks.success) - .catch(callbacks.error) -} - -const appConfig = (name, value, callbacks) => { - OCP.AppConfig.setValue('side_menu', name, value, callbacks) -} - -const saveSettings = (key) => { - const element = elements[key] - - if (!element) { - return - } - - let value - let name - - if (element.hasAttribute('data-checkbox')) { - name = element.getAttribute('data-name') - value = [] - - const inputs = document.querySelectorAll('input[name="' + name + '[]"]:checked') - - for (let input of inputs) { - value.push(input.value) - } - - value = JSON.stringify(value) - } else { - name = element.getAttribute('name') - value = element.value - } - - const size = elements.length - - if (name === 'cache') { - ++value - } - - const progress = document.querySelector('#side-menu-save-progress') - - progress.style.width = '40px' - progress.style.marginLeft = '5px' - - const callbacks = { - success: () => { - const percent = parseInt(((key + 1) * 100) / size) - - progress.setAttribute('value', percent) - - if (key < size - 1) { - saveSettings(key + 1) - } else { - location.reload() - } - }, - error: () => { - OC.msg.finishedError(selector, t('side_menu', 'Error while saving "' + element + '"')) - }, - } - - if (element.hasAttribute('data-personal')) { - userConfig(name, value, callbacks) - } else { - appConfig(name, value, callbacks) - } -} - -const elementToggler = (element) => { - let display = 'none' - - if (window.getComputedStyle(element).display === 'none') { - display = 'block' - } - - 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', () => { - $('*[data-toggle="tooltip"]').tooltip() - - if (document.querySelector('#side-menu-categories-custom')) { - const app = createApp(AdminCategoriesCustom) - app.mount('#side-menu-categories-custom') - } - - elements = document.querySelectorAll('.side-menu-setting') - - document.querySelector('#side-menu-save').addEventListener('click', (event) => { - event.preventDefault() - OC.msg.startSaving(selector) - - saveSettings(0) - }) - - const resets = document.querySelectorAll('.btn-reset') - - for (let btn of resets) { - btn.addEventListener('click', (event) => { - const target = event.target - const values = JSON.parse(target.getAttribute('data-reset')) - - target.classList.toggle('btn-reset--progress', true) - - for (let i in values) { - document.querySelector(`#${i}`).value = values[i] - } - - window.setTimeout(() => { - target.classList.toggle('btn-reset--progress', false) - }, 800) - }) - } - - const displays = document.querySelectorAll('.side-menu-display') - - for (let display of displays) { - display.addEventListener('click', (event) => { - const target = event.target - - for (let d of displays) { - d.classList.toggle('is-active', d === display) - } - - document.querySelector('#side-menu-always-displayed').value = target.getAttribute('data-alwaysdiplayed') - document.querySelector('#side-menu-big-menu').value = target.getAttribute('data-bigmenu') - document.querySelector('#side-menu-side-with-categories').value = target.getAttribute('data-sidewithcategories') - }) - } - - 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 - const name = target.getAttribute('name') - - let value = target.value - let id = null - - if (name === 'background-color-opacity') { - id = '#side-menu-background-color, #side-menu-background-color-to' - } else if (name === 'dark-mode-background-color-opacity') { - id = '#side-menu-dark-mode-background-color, #side-menu-dark-mode-background-color-to' - } - - if (id) { - document.querySelector(id).dispatchEvent(new CustomEvent('change')) - - return - } - - if (name === 'opener') { - const url = OC.generateUrl(`/apps/side_menu/img/${value}.svg`).replace('/index.php', '') - - value = `url(${url})` - } - - if (name === 'icon-invert-filter' || name === 'icon-opacity') { - value /= 100 - } - - if (['dark-mode-background-color', 'dark-mode-background-color-to'].indexOf(name) > -1) { - const opacity = parseInt((document.querySelector('#side-menu-dark-mode-background-color-opacity').value * 255) / 100) - - value = [value, opacity.toString(16)].join('') - } else if (['background-color', 'background-color-to'].indexOf(name) > -1) { - const opacity = parseInt((document.querySelector('#side-menu-background-color-opacity').value * 255) / 100) - - value = [value, opacity.toString(16)].join('') - } - - document.documentElement.style.setProperty('--side-menu-' + name, value) - }) - } - - for (let toggler of document.querySelectorAll('.side-menu-toggler')) { - toggler.addEventListener('click', (event) => { - const target = event.target - const element = document.querySelector(target.getAttribute('data-target')) - - elementToggler(element) - }) - } - - sortable('#categories-list .side-menu-setting-list', { - placeholderClass: 'side-menu-setting-list-drop', - }) - - try { - sortable('#categories-list .side-menu-setting-list')[0].addEventListener('sortstop', (e) => { - let value = [] - - for (let item of document.querySelectorAll('#categories-list .side-menu-setting-list-item')) { - value.push(item.getAttribute('data-id')) - } - - document.querySelector('input[name="categories-order"]').value = JSON.stringify(value) - }) - } catch (e) {} - - sortable('#apps-order-list .side-menu-setting-list', { - placeholderClass: 'side-menu-setting-list-drop', - }) - - try { - sortable('#apps-order-list .side-menu-setting-list')[0].addEventListener('sortstop', (e) => { - let value = [] - - for (let item of document.querySelectorAll('#apps-order-list .side-menu-setting-list-item')) { - value.push(item.getAttribute('data-id')) - } - - document.querySelector('input[name="apps-order"]').value = JSON.stringify(value) - }) - } catch (e) {} +waitContainer('#side-menu-admin-settings').then((selector) => { + const pinia = createPinia() + const app = createApp(AdminSettings) + app.use(pinia) + app.mixin({ methods: { t, n }}) + app.mount(selector) }) diff --git a/src/components/AdminCategoriesCustom.vue b/src/components/AdminCategoriesCustom.vue index 407ae06..c9259ff 100644 --- a/src/components/AdminCategoriesCustom.vue +++ b/src/components/AdminCategoriesCustom.vue @@ -102,101 +102,92 @@ along with this program. If not, see .
- + + diff --git a/src/scss/admin.scss b/src/scss/admin.scss index 911b939..fafdd14 100644 --- a/src/scss/admin.scss +++ b/src/scss/admin.scss @@ -114,6 +114,7 @@ .side-menu-setting-table { display: table; width: 100%; + padding: 10px; } .side-menu-setting-row { @@ -141,6 +142,10 @@ vertical-align: top; } +.side-menu-setting-label--middle { + vertical-align: middle; +} + .side-menu-setting-form { display: table-cell; min-width: 300px; @@ -218,3 +223,23 @@ border-color: #c681d4; color: #fff; } + +.side-menu-setting { + padding: 10px; + display: flex; + gap: 12px; +} + +.side-menu-setting-color-picker { + display: inline-block; + margin-right: 12px; + width: 60px; + height: 30px; + + &-value { + cursor: pointer; + width: 60px; + height: 30px; + border-radius: 6px; + } +} diff --git a/src/scss/menu.scss b/src/scss/menu.scss index 9e8c749..c1dd6cf 100644 --- a/src/scss/menu.scss +++ b/src/scss/menu.scss @@ -41,12 +41,40 @@ display: block; } } + + .side-menu-opener { + margin-top: 1px !important; + } + + &.side-menu-big { + max-width: 100%; + height: auto; + } + + &.side-menu-with-categories { + max-width: 290px; + height: 100vh; + + .side-menu-categories { + display: block; + padding: 0; + width: 100%; + } + + .side-menu-category { + padding: 10px 0; + } + } + + &.side-menu-big, &.side-menu-with-categories { + height: auto; + } } #header { .side-menu-opener { margin-left: 0px; - margin-top: -1px; + margin-top: 0px; } } @@ -111,20 +139,19 @@ display: none; } -#side-menu.hide-opener .side-menu-opener, -.side-menu-opener.hide, -#side-menu.hide { - display: none !important; -} - .side-menu-apps-list { - height: calc(100vh - 150px); + height: calc(100vh - 49px); + top: 49px; z-index: 2200; position: fixed; - top: 150px; width: 100%; max-width: 290px; overflow: auto; + + &.side-menu-apps-list--with-logo { + height: calc(100vh - 160px); + top: 160px; + } } .side-menu-app-icon { @@ -149,7 +176,8 @@ a:hover, a:focus, - &:active { + &:active, + &.active { background: var(--side-menu-current-app-background-color, #444); } } @@ -165,7 +193,6 @@ } .side-menu-header { - height: 150px; width: 100%; z-index: 2300; max-width: 290px; @@ -183,10 +210,6 @@ max-width: 295px; } -#side-menu.hide-opener .side-menu-logo { - margin-top: 10px; -} - #side-menu-loader { position: fixed; top: 0; @@ -202,28 +225,24 @@ } } -#side-menu.side-menu-big, -#side-menu.side-menu-with-categories { - max-width: 100%; - height: auto; -} +.side-menu-big, .side-menu-with-categories { + .side-menu-apps-list { + height: auto; + position: static; + max-width: 100vw; + overflow: auto; + } -.side-menu-big .side-menu-header, -.side-menu-with-categories .side-menu-header { - height: auto; -} + .side-menu-app { + a { + padding: 7px 0 7px 7px; + } + } -.side-menu-big .side-menu-apps-list, -.side-menu-with-categories .side-menu-apps-list { - height: auto; - position: static; - max-width: 100vw; - overflow: auto; -} - -.side-menu-big .side-menu-app a, -.side-menu-with-categories .side-menu-app a { - padding: 7px 0 7px 7px; + .side-menu-app-icon { + vertical-align: middle; + margin-top: -2px; + } } .side-menu-categories-wrapper { @@ -265,11 +284,6 @@ stroke: var(--side-menu-text-color, #fff); } -.side-menu-with-categories .side-menu-app-icon, -.side-menu-big .side-menu-app-icon { - vertical-align: middle; - margin-top: -2px; -} .side-menu-always-displayed { body { @@ -287,12 +301,6 @@ } .side-menu-apps-list { - height: 100vh; - top: 0; - overflow: hidden; - } - - .side-menu-apps-list--with-settings { height: calc(100vh - 49px); top: 49px; } @@ -331,32 +339,6 @@ right: 0 !important; margin-left: 0 !important; } - - .side-menu-search { - display: none; - } - - #body-settings, - #body-settings.body-settings-side-menu { - overflow-x: visible; - } -} - -#side-menu.side-menu-with-categories { - max-width: 290px; - height: 100vh; -} - -.side-menu-with-categories { - .side-menu-categories { - display: block; - padding: 0; - width: 100%; - } - - .side-menu-category { - padding: 10px 0; - } } .app-menu { @@ -390,10 +372,6 @@ height: 100vh; } - #side-menu.hide-opener.side-menu-big .side-menu-search { - float: none; - } - .side-menu-categories { display: block; padding: 0; diff --git a/templates/css/stylesheet.php b/templates/css/stylesheet.php index 5638629..0909b77 100644 --- a/templates/css/stylesheet.php +++ b/templates/css/stylesheet.php @@ -8,65 +8,28 @@ } - - #appmenu { - display: none; - } - - #appmenu + nav { - display: none; - } - - .app-hidden { - opacity: 0; - } - - #nextcloud { display: none; } - - .side-menu-logo { - display: none; + + #side-menu, .side-menu-apps-list { + + width: 55px; + + width: 52px; + } - .side-menu-header { - height: 50px; + #side-menu .side-menu-opener { + + margin-left: 1px; + + margin-left: 0px; + } - - .side-menu-apps-list { - height: calc(100vh - 49px); - top: 49px; - } - - #side-menu.hide-opener .side-menu-header .side-menu-opener.side-menu-closer { - visibility: hidden; - } - - #side-menu.hide-opener.side-menu-with-categories .side-menu-search { - float: none; - } - - - #side-menu, .side-menu-apps-list { - - width: 55px; - - width: 52px; - - } - - #side-menu .side-menu-opener { - - margin-left: 1px; - - margin-left: 0px; - - } - diff --git a/templates/js/script.php b/templates/js/script.php deleted file mode 100644 index 6550507..0000000 --- a/templates/js/script.php +++ /dev/null @@ -1,42 +0,0 @@ - { - let a = document.querySelector('#side-menu .side-menu-app.active a') - || document.querySelector('#side-menu .side-menu-app a') - - if (a) { - a.focus() - } - } - - document.querySelector('body').addEventListener('side-menu.apps', (e) => { - const apps = e.detail.apps; - }) - - body.addEventListener('side-menu.ready', () => { - const sideMenu = document.querySelector('#side-menu') - - - const sideMenuObserver = new MutationObserver((e) => { - if (body.getAttribute('id') !== 'body-settings') { - return - } - - body.classList.toggle('body-settings-side-menu', sideMenu.classList.contains('open')) - }) - - sideMenuObserver.observe(sideMenu, { - attributes: true, - attributeFilter: ['class'], - childList: false, - characterData: false - }) - }) -})(); diff --git a/templates/settings/admin-form.php b/templates/settings/admin-form.php index 1053b04..9666f08 100644 --- a/templates/settings/admin-form.php +++ b/templates/settings/admin-form.php @@ -20,1130 +20,7 @@ use OCP\IURLGenerator; use OCP\IConfig; use OCA\SideMenu\AppInfo\Application; -vendor_script('side_menu', 'html5sortable.min'); -script('side_menu', 'admin'); -style('side_menu', 'admin'); - -$urlGenerator = \OC::$server[IURLGenerator::class]; -$cacheSize = floor(mb_strlen(\OC::$server[IConfig::class]->getAppValue(Application::APP_ID, 'cache-categories', ''), '8bit') / 1024); - -$choicesYesNo = [ - 'No' => '0', - 'Yes' => '1', -]; - -$choicesSizes = [ - 'Hidden' => 'hidden', - 'Small' => 'small', - 'Normal' => 'normal', - 'Big' => 'big', -]; - -$labelShowHideApps = 'Show and hide the list of applications'; -$labelReset = 'Reset to default'; -$labelDefault = 'Default'; -$labelWithCategories = 'With categories'; -$labelBigMenu = 'Big menu'; -$labelAlwaysDisplayed = 'Always displayed'; - +script('side_menu', 'side_menu-admin'); ?> -
-
-

- t('Panel')); ?> -

- - !$_['always-displayed'] && !$_['big-menu'] && !$_['side-with-categories'], - 'always-displayed' => $_['always-displayed'] && !$_['big-menu'] && !$_['side-with-categories'], - 'side-with-categories' => $_['side-with-categories'] && !$_['always-displayed'] && !$_['big-menu'], - 'big-menu' => $_['big-menu'] && !$_['always-displayed'] && !$_['side-with-categories'], - ]; - ?> - -
- -
-

- <?php p($l->t($labelDefault)); ?> -

- -
- -
-

- <?php p($l->t($labelWithCategories)); ?> -

- -
- -
-

- <?php p($l->t($labelBigMenu)); ?> -

- -
- -
-

t('Not compatible with touch screens.')); ?>

-

- <?php p($l->t($labelAlwaysDisplayed)); ?> -

- - - - -
- -
-

- t('Colors')); ?> - - t('Live preview')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -
-
-
- t('Background color')); ?> -
-
- - - -
-
- - t('Transparent')); ?> - - - - - - t('Opaque')); ?> - -
-
- -
-
- -
-
-
- t('Background color of current app')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Text color')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Loader')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Icon')); ?> -
-
-
- - t('Same color')); ?> - - - - - - t('Opposite color')); ?> - -
- -
- - t('Transparent')); ?> - - - - - - t('Opaque')); ?> - -
-
-
-
- -
- 'side-menu-opener', - 'Default (dark)' => 'side-menu-opener-dark', - 'Hamburger' => 'side-menu-opener-hamburger', - 'Hamburger (dark)' => 'side-menu-opener-hamburger-dark', - 'Hamburger 2' => 'side-menu-opener-hamburger-2', - 'Hamburger 2 (dark)' => 'side-menu-opener-hamburger-2-dark', - ]; - ?> -
-
- t('Icon')); ?> -
-
- -
-
-
- -

- t('Dark mode colors')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -

- t('This parameters are used when Dark theme or Breeze Dark Theme are enabled.'); ?> -

- -
-
-
- t('Background color')); ?> -
-
- - - -
- -
- - t('Transparent')); ?> - - - - - - t('Opaque')); ?> - -
-
-
-
- -
-
-
- t('Background color of current app')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Text color')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Loader')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Icon')); ?> -
-
-
- - t('Same color')); ?> - - - - - - t('Opposite color')); ?> - -
- -
- - t('Transparent')); ?> - - - - - - t('Opaque')); ?> - -
-
-
-
- -
- 'side-menu-opener', - 'Default (dark)' => 'side-menu-opener-dark', - 'Hamburger' => 'side-menu-opener-hamburger', - 'Hamburger (dark)' => 'side-menu-opener-hamburger-dark', - 'Hamburger 2' => 'side-menu-opener-hamburger-2', - 'Hamburger 2 (dark)' => 'side-menu-opener-hamburger-2-dark', - ]; - ?> -
-
- t('Icon')); ?> -
-
- -
-
-
-
- -
-

- t('Opener')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -
-
- 'before', - 'After the logo' => 'after', - ]; - ?> -
- t('Position')); ?> -
-
- -
-
- -
-
- t('Show only the opener (hidden logo)')); ?> -
-
- -
-
- -
-
- t('Do not display the side menu and the opener if there is no application (eg: public pages).')); ?> -
-
- -
-
- -
-
- t('Open the menu when the mouse is hover the opener (automatically disabled on touch screens)')); ?> - -
- t('This is the automatic behavior when the menu is always displayed.')); ?> -
-
- -
-
-
-
- -
-
-
-
- t('Display the logo')); ?> - -
- t($labelDefault)); ?> -
-
-
- -
-
- -
-
- t('Use the avatar instead of the logo')); ?> - -
- t($labelDefault)); ?> -
-
-
- -
-
- -
-
- t('The logo is a link to the default app')); ?> - -
- t($labelDefault)); ?> -
-
-
- -
-
- -
-
- t('Apps that should not be displayed in the menu')); ?> - -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
-
-
- - 🖱️ t($labelShowHideApps)); ?> - - - -
-
- -
-
- t('Show the link to settings')); ?> -
-
- -
-
- -
-
- t('Icons and texts')); ?> -
-
- - - -
-
- -
-
- t('Open apps in new tab')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - - -
-
- -
-
- t('Loader enabled')); ?> -
-
- -
-
-
-
- -
-

- t('Top menu')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -
-
-
- t('Applications kept in the top menu')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - - -
-
- -
-
- t('Applications kept in the top menu but also shown in side menu')); ?> -
- t('These applications must be selected in the previous option.')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - - -
-
-
-
- t('Hide labels on mouse over')); ?> -
- '2'] - ); - ?> -
- -
-
-
-
- -
-

- t('Applications')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -
-
-
- t('Customize sorting')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - -
- - - - ' name="apps-order" class="side-menu-setting" id="side-menu-apps-order"> -
-
-
-
- - -
-

- t('Categories')); ?> -

- -
- t($labelWithCategories)); ?> - t($labelBigMenu)); ?> -
- -
-
- 'default', - 'Customed' => 'custom', - ]; - ?> -
- t('Order by')); ?> -
-
- -
-
- -
-
- t('Custom categories')); ?> -
-
- - -
-
-
-
- -
-
- t('Customize application categories')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - - - - -
-
- -
-
- t('Customize sorting')); ?> -
-
- - 🖱️ t('Show and hide the list of categories')); ?> - - - - - ' name="categories-order" class="side-menu-setting"> -
-
-
-
- -
-

- t('Tips')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -

- t('Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.'); ?> -

-
- -
-
-
-
- t('The menu is enabled by default for users')); ?> -
- t('Except when the configuration is forced.')); ?> -
-
- -
-
- -
-
- t('Force this configuration to users')); ?> -
-
- -
-
-
- - -
- -
- - - - - - - - - - -
- -
- - t('You like this app and you want to support me?')); ?> - - - - - -
-
-
+
diff --git a/templates/settings/admin-form.php.bk b/templates/settings/admin-form.php.bk new file mode 100644 index 0000000..492b8df --- /dev/null +++ b/templates/settings/admin-form.php.bk @@ -0,0 +1,1148 @@ +. + */ + +use OCP\IURLGenerator; +use OCP\IConfig; +use OCA\SideMenu\AppInfo\Application; + +vendor_script('side_menu', 'html5sortable.min'); +script('side_menu', 'side_menu-admin'); + +$urlGenerator = \OC::$server[IURLGenerator::class]; +$cacheSize = floor(mb_strlen(\OC::$server[IConfig::class]->getAppValue(Application::APP_ID, 'cache-categories', ''), '8bit') / 1024); + +$choicesYesNo = [ + 'No' => '0', + 'Yes' => '1', +]; + +$choicesSizes = [ + 'Hidden' => 'hidden', + 'Small' => 'small', + 'Normal' => 'normal', + 'Big' => 'big', +]; + +$labelShowHideApps = 'Show and hide the list of applications'; +$labelReset = 'Reset to default'; +$labelDefault = 'Default'; +$labelWithCategories = 'With categories'; +$labelBigMenu = 'Big menu'; +$labelAlwaysDisplayed = 'Always displayed'; + +?> +
+ +
+

+ t('Panel')); ?> +

+ + !$_['always-displayed'] && !$_['big-menu'] && !$_['side-with-categories'], + 'always-displayed' => $_['always-displayed'] && !$_['big-menu'] && !$_['side-with-categories'], + 'side-with-categories' => $_['side-with-categories'] && !$_['always-displayed'] && !$_['big-menu'], + 'big-menu' => $_['big-menu'] && !$_['always-displayed'] && !$_['side-with-categories'], + ]; + ?> + +
+ +
+

+ <?php p($l->t($labelDefault)); ?> +

+ +
+ +
+

+ <?php p($l->t($labelWithCategories)); ?> +

+ +
+ +
+

+ <?php p($l->t($labelBigMenu)); ?> +

+ +
+ +
+

t('Not compatible with touch screens.')); ?>

+

+ <?php p($l->t($labelAlwaysDisplayed)); ?> +

+ + + + +
+ +
+

+ t('Colors')); ?> + + t('Live preview')); ?> +

+ +
+ t($labelDefault)); ?> + t($labelWithCategories)); ?> + t($labelBigMenu)); ?> + t($labelAlwaysDisplayed)); ?> +
+ +
+
+
+ t('Background color')); ?> +
+
+ + + +
+
+ + t('Transparent')); ?> + + + + + + t('Opaque')); ?> + +
+
+ +
+
+ +
+
+
+ t('Background color of current app')); ?> +
+
+ + +
+
+
+
+ +
+
+
+ t('Text color')); ?> +
+
+ + +
+
+
+
+ +
+
+
+ t('Loader')); ?> +
+
+ + +
+
+
+
+ +
+
+
+ t('Icon')); ?> +
+
+
+ + t('Same color')); ?> + + + + + + t('Opposite color')); ?> + +
+ +
+ + t('Transparent')); ?> + + + + + + t('Opaque')); ?> + +
+
+
+
+ +
+ 'side-menu-opener', + 'Default (dark)' => 'side-menu-opener-dark', + 'Hamburger' => 'side-menu-opener-hamburger', + 'Hamburger (dark)' => 'side-menu-opener-hamburger-dark', + 'Hamburger 2' => 'side-menu-opener-hamburger-2', + 'Hamburger 2 (dark)' => 'side-menu-opener-hamburger-2-dark', + ]; + ?> +
+
+ t('Icon')); ?> +
+
+ +
+
+
+ +

+ t('Dark mode colors')); ?> +

+ +
+ t($labelDefault)); ?> + t($labelWithCategories)); ?> + t($labelBigMenu)); ?> + t($labelAlwaysDisplayed)); ?> +
+ +

+ t('This parameters are used when Dark theme or Breeze Dark Theme are enabled.'); ?> +

+ +
+
+
+ t('Background color')); ?> +
+
+ + + +
+ +
+ + t('Transparent')); ?> + + + + + + t('Opaque')); ?> + +
+
+
+
+ +
+
+
+ t('Background color of current app')); ?> +
+
+ + +
+
+
+
+ +
+
+
+ t('Text color')); ?> +
+
+ + +
+
+
+
+ +
+
+
+ t('Loader')); ?> +
+
+ + +
+
+
+
+ +
+
+
+ t('Icon')); ?> +
+
+
+ + t('Same color')); ?> + + + + + + t('Opposite color')); ?> + +
+ +
+ + t('Transparent')); ?> + + + + + + t('Opaque')); ?> + +
+
+
+
+ +
+ 'side-menu-opener', + 'Default (dark)' => 'side-menu-opener-dark', + 'Hamburger' => 'side-menu-opener-hamburger', + 'Hamburger (dark)' => 'side-menu-opener-hamburger-dark', + 'Hamburger 2' => 'side-menu-opener-hamburger-2', + 'Hamburger 2 (dark)' => 'side-menu-opener-hamburger-2-dark', + ]; + ?> +
+
+ t('Icon')); ?> +
+
+ +
+
+
+
+ +
+

+ t('Opener')); ?> +

+ +
+ t($labelDefault)); ?> + t($labelWithCategories)); ?> + t($labelBigMenu)); ?> + t($labelAlwaysDisplayed)); ?> +
+ +
+
+ 'before', + 'After the logo' => 'after', + ]; + ?> +
+ t('Position')); ?> +
+
+ +
+
+ +
+
+ t('Show only the opener (hidden logo)')); ?> +
+
+ +
+
+ +
+
+ t('Do not display the side menu and the opener if there is no application (eg: public pages).')); ?> +
+
+ +
+
+ +
+
+ t('Open the menu when the mouse is hover the opener (automatically disabled on touch screens)')); ?> + +
+ t('This is the automatic behavior when the menu is always displayed.')); ?> +
+
+ +
+
+
+
+ +
+
+
+
+ t('Display the logo')); ?> + +
+ t($labelDefault)); ?> +
+
+
+ +
+
+ +
+
+ t('Use the avatar instead of the logo')); ?> + +
+ t($labelDefault)); ?> +
+
+
+ +
+
+ +
+
+ t('The logo is a link to the default app')); ?> + +
+ t($labelDefault)); ?> +
+
+
+ +
+
+ +
+
+ t('Apps that should not be displayed in the menu')); ?> + +
+ t($labelDefault)); ?> + t($labelWithCategories)); ?> + t($labelBigMenu)); ?> + t($labelAlwaysDisplayed)); ?> +
+
+
+ + 🖱️ t($labelShowHideApps)); ?> + + + +
+
+ +
+
+ t('Show the link to settings')); ?> +
+
+ +
+
+ +
+
+ t('Icons and texts')); ?> +
+
+ + + +
+
+ +
+
+ t('Open apps in new tab')); ?> +
+
+ + 🖱️ t($labelShowHideApps)); ?> + + + +
+
+ +
+
+ t('Loader enabled')); ?> +
+
+ +
+
+
+
+ +
+

+ t('Top menu')); ?> +

+ +
+ t($labelDefault)); ?> + t($labelWithCategories)); ?> + t($labelBigMenu)); ?> + t($labelAlwaysDisplayed)); ?> +
+ +
+
+
+ t('Applications kept in the top menu')); ?> +
+
+ + 🖱️ t($labelShowHideApps)); ?> + + + +
+
+ +
+
+ t('Applications kept in the top menu but also shown in side menu')); ?> +
+ t('These applications must be selected in the previous option.')); ?> +
+
+ + 🖱️ t($labelShowHideApps)); ?> + + + +
+
+
+
+ t('Hide labels on mouse over')); ?> +
+ '2'] + ); + ?> +
+ +
+
+
+
+ +
+

+ t('Applications')); ?> +

+ +
+ t($labelDefault)); ?> + t($labelWithCategories)); ?> + t($labelBigMenu)); ?> + t($labelAlwaysDisplayed)); ?> +
+ +
+
+
+ t('Customize sorting')); ?> +
+
+ + 🖱️ t($labelShowHideApps)); ?> + + +
+ + + + ' name="apps-order" class="side-menu-setting" id="side-menu-apps-order"> +
+
+
+
+ + +
+

+ t('Categories')); ?> +

+ +
+ t($labelWithCategories)); ?> + t($labelBigMenu)); ?> +
+ +
+
+ 'default', + 'Customed' => 'custom', + ]; + ?> +
+ t('Order by')); ?> +
+
+ +
+
+ +
+
+ t('Custom categories')); ?> +
+
+ + +
+
+
+
+ +
+
+ t('Customize application categories')); ?> +
+
+ + 🖱️ t($labelShowHideApps)); ?> + + + + + +
+
+ +
+
+ t('Customize sorting')); ?> +
+
+ + 🖱️ t('Show and hide the list of categories')); ?> + + + + + ' name="categories-order" class="side-menu-setting"> +
+
+
+
+ +
+

+ t('Tips')); ?> +

+ +
+ t($labelDefault)); ?> + t($labelWithCategories)); ?> + t($labelBigMenu)); ?> + t($labelAlwaysDisplayed)); ?> +
+ +

+ t('Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.'); ?> +

+
+ +
+
+
+
+ t('The menu is enabled by default for users')); ?> +
+ t('Except when the configuration is forced.')); ?> +
+
+ +
+
+ +
+
+ t('Force this configuration to users')); ?> +
+
+ +
+
+
+ + +
+ +
+ + + + + + + + + + +
+ +
+ + t('You like this app and you want to support me?')); ?> + + + + + +
+
+
diff --git a/webpack.config.js b/webpack.config.js index c9ca6de..e971ab1 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -16,7 +16,7 @@ module.exports = { devtool: "inline-source-map", entry: { menu: path.resolve(path.join('src', 'menu.js')), - // admin: path.resolve(path.join('src', 'admin.js')), + admin: path.resolve(path.join('src', 'admin.js')), }, output: { path: path.resolve('./js'), diff --git a/webpack.rules.js b/webpack.rules.js index 101f29b..4314a8f 100644 --- a/webpack.rules.js +++ b/webpack.rules.js @@ -3,6 +3,10 @@ module.exports = { test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'], }, + css: { + test: /\.css$/, + use: ['style-loader', 'css-loader'], + }, vue: { test: /\.vue$/, loader: 'vue-loader', From 8c5c43dafa135dfe75ce2fcc3b5675a3f410e51f Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Wed, 9 Apr 2025 19:16:58 +0200 Subject: [PATCH 121/228] remove archive of admin form file --- templates/settings/admin-form.php.bk | 1148 -------------------------- 1 file changed, 1148 deletions(-) delete mode 100644 templates/settings/admin-form.php.bk diff --git a/templates/settings/admin-form.php.bk b/templates/settings/admin-form.php.bk deleted file mode 100644 index 492b8df..0000000 --- a/templates/settings/admin-form.php.bk +++ /dev/null @@ -1,1148 +0,0 @@ -. - */ - -use OCP\IURLGenerator; -use OCP\IConfig; -use OCA\SideMenu\AppInfo\Application; - -vendor_script('side_menu', 'html5sortable.min'); -script('side_menu', 'side_menu-admin'); - -$urlGenerator = \OC::$server[IURLGenerator::class]; -$cacheSize = floor(mb_strlen(\OC::$server[IConfig::class]->getAppValue(Application::APP_ID, 'cache-categories', ''), '8bit') / 1024); - -$choicesYesNo = [ - 'No' => '0', - 'Yes' => '1', -]; - -$choicesSizes = [ - 'Hidden' => 'hidden', - 'Small' => 'small', - 'Normal' => 'normal', - 'Big' => 'big', -]; - -$labelShowHideApps = 'Show and hide the list of applications'; -$labelReset = 'Reset to default'; -$labelDefault = 'Default'; -$labelWithCategories = 'With categories'; -$labelBigMenu = 'Big menu'; -$labelAlwaysDisplayed = 'Always displayed'; - -?> -
- -
-

- t('Panel')); ?> -

- - !$_['always-displayed'] && !$_['big-menu'] && !$_['side-with-categories'], - 'always-displayed' => $_['always-displayed'] && !$_['big-menu'] && !$_['side-with-categories'], - 'side-with-categories' => $_['side-with-categories'] && !$_['always-displayed'] && !$_['big-menu'], - 'big-menu' => $_['big-menu'] && !$_['always-displayed'] && !$_['side-with-categories'], - ]; - ?> - -
- -
-

- <?php p($l->t($labelDefault)); ?> -

- -
- -
-

- <?php p($l->t($labelWithCategories)); ?> -

- -
- -
-

- <?php p($l->t($labelBigMenu)); ?> -

- -
- -
-

t('Not compatible with touch screens.')); ?>

-

- <?php p($l->t($labelAlwaysDisplayed)); ?> -

- - - - -
- -
-

- t('Colors')); ?> - - t('Live preview')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -
-
-
- t('Background color')); ?> -
-
- - - -
-
- - t('Transparent')); ?> - - - - - - t('Opaque')); ?> - -
-
- -
-
- -
-
-
- t('Background color of current app')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Text color')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Loader')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Icon')); ?> -
-
-
- - t('Same color')); ?> - - - - - - t('Opposite color')); ?> - -
- -
- - t('Transparent')); ?> - - - - - - t('Opaque')); ?> - -
-
-
-
- -
- 'side-menu-opener', - 'Default (dark)' => 'side-menu-opener-dark', - 'Hamburger' => 'side-menu-opener-hamburger', - 'Hamburger (dark)' => 'side-menu-opener-hamburger-dark', - 'Hamburger 2' => 'side-menu-opener-hamburger-2', - 'Hamburger 2 (dark)' => 'side-menu-opener-hamburger-2-dark', - ]; - ?> -
-
- t('Icon')); ?> -
-
- -
-
-
- -

- t('Dark mode colors')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -

- t('This parameters are used when Dark theme or Breeze Dark Theme are enabled.'); ?> -

- -
-
-
- t('Background color')); ?> -
-
- - - -
- -
- - t('Transparent')); ?> - - - - - - t('Opaque')); ?> - -
-
-
-
- -
-
-
- t('Background color of current app')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Text color')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Loader')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Icon')); ?> -
-
-
- - t('Same color')); ?> - - - - - - t('Opposite color')); ?> - -
- -
- - t('Transparent')); ?> - - - - - - t('Opaque')); ?> - -
-
-
-
- -
- 'side-menu-opener', - 'Default (dark)' => 'side-menu-opener-dark', - 'Hamburger' => 'side-menu-opener-hamburger', - 'Hamburger (dark)' => 'side-menu-opener-hamburger-dark', - 'Hamburger 2' => 'side-menu-opener-hamburger-2', - 'Hamburger 2 (dark)' => 'side-menu-opener-hamburger-2-dark', - ]; - ?> -
-
- t('Icon')); ?> -
-
- -
-
-
-
- -
-

- t('Opener')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -
-
- 'before', - 'After the logo' => 'after', - ]; - ?> -
- t('Position')); ?> -
-
- -
-
- -
-
- t('Show only the opener (hidden logo)')); ?> -
-
- -
-
- -
-
- t('Do not display the side menu and the opener if there is no application (eg: public pages).')); ?> -
-
- -
-
- -
-
- t('Open the menu when the mouse is hover the opener (automatically disabled on touch screens)')); ?> - -
- t('This is the automatic behavior when the menu is always displayed.')); ?> -
-
- -
-
-
-
- -
-
-
-
- t('Display the logo')); ?> - -
- t($labelDefault)); ?> -
-
-
- -
-
- -
-
- t('Use the avatar instead of the logo')); ?> - -
- t($labelDefault)); ?> -
-
-
- -
-
- -
-
- t('The logo is a link to the default app')); ?> - -
- t($labelDefault)); ?> -
-
-
- -
-
- -
-
- t('Apps that should not be displayed in the menu')); ?> - -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
-
-
- - 🖱️ t($labelShowHideApps)); ?> - - - -
-
- -
-
- t('Show the link to settings')); ?> -
-
- -
-
- -
-
- t('Icons and texts')); ?> -
-
- - - -
-
- -
-
- t('Open apps in new tab')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - - -
-
- -
-
- t('Loader enabled')); ?> -
-
- -
-
-
-
- -
-

- t('Top menu')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -
-
-
- t('Applications kept in the top menu')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - - -
-
- -
-
- t('Applications kept in the top menu but also shown in side menu')); ?> -
- t('These applications must be selected in the previous option.')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - - -
-
-
-
- t('Hide labels on mouse over')); ?> -
- '2'] - ); - ?> -
- -
-
-
-
- -
-

- t('Applications')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -
-
-
- t('Customize sorting')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - -
- - - - ' name="apps-order" class="side-menu-setting" id="side-menu-apps-order"> -
-
-
-
- - -
-

- t('Categories')); ?> -

- -
- t($labelWithCategories)); ?> - t($labelBigMenu)); ?> -
- -
-
- 'default', - 'Customed' => 'custom', - ]; - ?> -
- t('Order by')); ?> -
-
- -
-
- -
-
- t('Custom categories')); ?> -
-
- - -
-
-
-
- -
-
- t('Customize application categories')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - - - - -
-
- -
-
- t('Customize sorting')); ?> -
-
- - 🖱️ t('Show and hide the list of categories')); ?> - - - - - ' name="categories-order" class="side-menu-setting"> -
-
-
-
- -
-

- t('Tips')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -

- t('Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.'); ?> -

-
- -
-
-
-
- t('The menu is enabled by default for users')); ?> -
- t('Except when the configuration is forced.')); ?> -
-
- -
-
- -
-
- t('Force this configuration to users')); ?> -
-
- -
-
-
- - -
- -
- - - - - - - - - - -
- -
- - t('You like this app and you want to support me?')); ?> - - - - - -
-
-
From f9c3f96919eb7d6ae0a221824d8139358ed54897 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Thu, 10 Apr 2025 19:54:03 +0200 Subject: [PATCH 122/228] migrate admin settings --- .gitignore | 2 + lib/AppInfo/Application.php | 8 + lib/Controller/AdminSettingController.php | 132 +++- lib/Controller/CssController.php | 9 +- lib/Service/Color.php | 31 + src/admin.js | 2 +- src/components/settings/MenuDisplay.vue | 8 +- src/components/settings/SectionTitle.vue | 19 + src/components/settings/TableLabel.vue | 23 +- src/components/settings/TableValue.vue | 5 +- .../settings/form/FormAppPicker.vue | 82 +++ .../settings/form/FormColorPicker.vue | 17 + src/components/settings/form/FormOpener.vue | 20 + src/components/settings/form/FormRange.vue | 56 ++ src/components/settings/form/FormSelect.vue | 48 ++ src/components/settings/form/FormSize.vue | 18 + src/components/settings/form/FormYesNo.vue | 12 + src/lib/menu.js | 3 +- src/menus/SideMenuWithCategories.vue | 13 +- src/menus/SimpleSideMenu.vue | 23 +- src/menus/TopWideMenu.vue | 13 +- src/pages/AdminSettings.vue | 563 ++++++++++++++++-- src/scss/admin.scss | 6 +- src/scss/menu.scss | 7 +- src/store/config.js | 12 + 25 files changed, 1024 insertions(+), 108 deletions(-) create mode 100644 src/components/settings/SectionTitle.vue create mode 100644 src/components/settings/form/FormAppPicker.vue create mode 100644 src/components/settings/form/FormColorPicker.vue create mode 100644 src/components/settings/form/FormOpener.vue create mode 100644 src/components/settings/form/FormRange.vue create mode 100644 src/components/settings/form/FormSelect.vue create mode 100644 src/components/settings/form/FormSize.vue create mode 100644 src/components/settings/form/FormYesNo.vue diff --git a/.gitignore b/.gitignore index d10e458..7cadaec 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ /package-lock.json !/l10n/.gitkeep /yarn*.log +/src/admin.js.bk +/templates/settings/admin-form.php.bk diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 0b9fd24..370750a 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -13,6 +13,7 @@ use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; +use OCA\Theming\ThemingDefaults; use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\INavigationManager; @@ -20,6 +21,7 @@ use OCP\IUserSession; use OCP\L10N\IFactory; use OCP\Util; use Psr\Container\ContainerInterface; +use OCA\SideMenu\Service\Color; /** * class Application. @@ -81,6 +83,12 @@ class Application extends App implements IBootstrap $c->get(IConfig::class), ); }); + + $context->registerService(Color::class, function (ContainerInterface $c) { + return new Color( + $c->get(ThemingDefaults::class), + ); + }); } public function boot(IBootContext $context): void diff --git a/lib/Controller/AdminSettingController.php b/lib/Controller/AdminSettingController.php index 279a34c..839d65c 100644 --- a/lib/Controller/AdminSettingController.php +++ b/lib/Controller/AdminSettingController.php @@ -20,14 +20,17 @@ namespace OCA\SideMenu\Controller; use OCA\SideMenu\AppInfo\Application; +use OCA\SideMenu\Service\ConfigProxy; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\Attribute\FrontpageRoute; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\DataDownloadResponse; +use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\RedirectResponse; use OCP\IConfig; use OCP\IRequest; use OCP\IURLGenerator; +use OCA\SideMenu\Service\Color; class AdminSettingController extends Controller { @@ -35,7 +38,9 @@ class AdminSettingController extends Controller $appName, IRequest $request, protected IConfig $config, - protected IURLGenerator $urlGenerator + protected ConfigProxy $configProxy, + protected IURLGenerator $urlGenerator, + protected Color $color, ) { parent::__construct($appName, $request); } @@ -76,4 +81,129 @@ class AdminSettingController extends Controller 'text/json' ); } + + #[NoCSRFRequired] + #[FrontpageRoute(verb: 'GET', url: '/admin/config')] + public function configuration(): JSONResponse + { + $keys = $this->config->getAppKeys(Application::APP_ID); + $booleans = [ + 'opener-only', + 'opener-hover', + 'display-logo', + 'use-avatar', + 'add-logo-link', + 'show-settings', + 'loader-enabled', + 'top-menu-mouse-over-hidden-label', + 'always-displayed', + 'enabled', + 'force', + 'big-menu', + 'external-sites-in-top-menu', + 'force-light-icon', + 'side-with-categories', + 'default-enabled', + ]; + + $arrays = [ + 'apps-categories-custom', + 'big-menu-hidden-apps', + 'apps-order', + 'categories-custom', + 'categories-order', + 'target-blank-apps', + 'top-menu-apps', + 'top-side-menu-apps', + ]; + + $integers = [ + 'background-color-opacity', + 'dark-mode-background-color-opacity', + 'dark-mode-icon-invert-filter', + 'dark-mode-icon-opacity', + 'icon-invert-filter', + 'icon-opacity', + 'target-blank-mode', + 'top-menu-mouse-over-hidden-label', + ]; + + $defaults = [ + 'opener-only' => '0', + 'opener-hover' => '0', + 'display-logo' => '1', + 'use-avatar' => '0', + 'add-logo-link' => '1', + 'show-settings' => '0', + 'loader-enabled' => '1', + 'top-menu-mouse-over-hidden-label' => '0', + 'always-displayed' => '0', + 'enabled' => '1', + 'force' => '0', + 'big-menu' => '0', + 'external-sites-in-top-menu' => '0', + 'force-light-icon' => '0', + 'side-with-categories' => '0', + 'cache' => '1', + 'default-enabled' => '1', + + 'apps-categories-custom' => '[]', + 'big-menu-hidden-apps' => '[]', + 'apps-order' => '[]', + 'categories-custom' => '[]', + 'categories-order' => '[]', + 'target-blank-apps' => '[]', + 'top-menu-apps' => '[]', + 'top-side-menu-apps' => '[]', + 'cache-categories' => '[]', + + 'background-color-opacity' => '100', + 'dark-mode-background-color-opacity' => '100', + 'dark-mode-icon-invert-filter' => '0', + 'dark-mode-icon-opacity' => '100', + 'icon-invert-filter' => '0', + 'icon-opacity' => '100', + 'top-menu-mouse-over-hidden-label' => '0', + + 'opener' => 'side-menu-opener', + 'dark-mode-opener' => 'side-menu-opener', + 'size-icon' => 'normal', + 'size-text' => 'normal', + 'opener-position' => 'before', + + 'background-color' => $this->color->getPrimaryColor(), + 'background-color-to' => $this->color->getLightenPrimaryColor(), + 'current-app-background-color' => $this->color->getDarkenPrimaryColor(), + 'text-color' => $this->color->getTextColorPrimary(), + 'loader-color' => $this->color->getLightenPrimaryColor(), + + 'dark-mode-background-color' => $this->color->getDarkenPrimaryColor(), + 'dark-mode-background-color-to' => $this->color->getDarkenPrimaryColor(), + 'dark-mode-current-app-background-color' => $this->color->getDarkenPrimaryColor2(), + 'dark-mode-text-color' => $this->color->getTextColorPrimary(), + 'dark-mode-loader-color' => $this->color->getLightenPrimaryColor(), + + 'categories-order-type' => 'default', + ]; + + $config = []; + + foreach ($keys as $key) { + if (!isset($defaults[$key])) { + continue; + } + + if (in_array($key, $booleans)) { + $config[$key] = $this->configProxy->getAppValueBool($key, $defaults[$key]); + } elseif (in_array($key, $arrays)) { + $config[$key] = $this->configProxy->getAppValueArray($key, $defaults[$key]); + } elseif (in_array($key, $integers)) { + $config[$key] = $this->configProxy->getAppValueInt($key, $defaults[$key]); + } else { + $config[$key] = $this->configProxy->getAppValue($key, $defaults[$key]); + } + } + + return new JSONResponse($config); + } } diff --git a/lib/Controller/CssController.php b/lib/Controller/CssController.php index 5b3a2dd..cf855cd 100644 --- a/lib/Controller/CssController.php +++ b/lib/Controller/CssController.php @@ -95,11 +95,10 @@ class CssController extends Controller $isDarkMode = ($isAccessibilityAppEnabled && $isDarkThemeUserEnabled) || ($isBreezeDarkAppEnabled && $isBreezeDarkUserEnabled); - $primaryColor = $this->theming->getColorPrimary(); - $lightenPrimaryColor = $this->color->adjustBrightness($primaryColor, 0.2); - $darkenPrimaryColor = $this->color->adjustBrightness($primaryColor, -0.2); - $darkenPrimaryColor2 = $this->color->adjustBrightness($primaryColor, -0.3); - $textColor = $this->theming->getTextColorPrimary(); + $lightenPrimaryColor = $this->color->getLightenPrimaryColor(); + $darkenPrimaryColor = $this->color->getDarkenPrimaryColor(); + $darkenPrimaryColor2 = $this->color->getDarkenPrimaryColor2(); + $textColor = $this->color->getTextColorPrimary(); if ($isDarkMode) { $backgroundColor = $this->config->getAppValue('dark-mode-background-color', $darkenPrimaryColor); diff --git a/lib/Service/Color.php b/lib/Service/Color.php index cf90dd6..98e4ed5 100644 --- a/lib/Service/Color.php +++ b/lib/Service/Color.php @@ -2,6 +2,8 @@ namespace OCA\SideMenu\Service; +use OCA\Theming\ThemingDefaults; + /** * class Color. * @@ -9,6 +11,10 @@ namespace OCA\SideMenu\Service; */ class Color { + public function __construct(protected ThemingDefaults $theming) + { + } + /** * @thanks https://stackoverflow.com/posts/54393956/revision */ @@ -31,4 +37,29 @@ class Color return '#'.implode($hexCode); } + + public function getPrimaryColor() + { + return $this->theming->getColorPrimary(); + } + + public function getLightenPrimaryColor() + { + return $this->adjustBrightness($this->getPrimaryColor(), 0.2); + } + + public function getDarkenPrimaryColor() + { + return $this->adjustBrightness($this->getPrimaryColor(), -0.2); + } + + public function getDarkenPrimaryColor2() + { + return $this->adjustBrightness($this->getPrimaryColor(), -0.3); + } + + public function getTextColorPrimary() + { + return $this->theming->getTextColorPrimary(); + } } diff --git a/src/admin.js b/src/admin.js index cf5e607..1749f6f 100644 --- a/src/admin.js +++ b/src/admin.js @@ -27,6 +27,6 @@ waitContainer('#side-menu-admin-settings').then((selector) => { const pinia = createPinia() const app = createApp(AdminSettings) app.use(pinia) - app.mixin({ methods: { t, n }}) + app.mixin({ methods: { t, n } }) app.mount(selector) }) diff --git a/src/components/settings/MenuDisplay.vue b/src/components/settings/MenuDisplay.vue index 789e165..fd65a0f 100644 --- a/src/components/settings/MenuDisplay.vue +++ b/src/components/settings/MenuDisplay.vue @@ -1,6 +1,4 @@ - + diff --git a/src/components/settings/SectionTitle.vue b/src/components/settings/SectionTitle.vue new file mode 100644 index 0000000..c17dc45 --- /dev/null +++ b/src/components/settings/SectionTitle.vue @@ -0,0 +1,19 @@ + + + + + diff --git a/src/components/settings/TableLabel.vue b/src/components/settings/TableLabel.vue index 535de47..0e5a5a6 100644 --- a/src/components/settings/TableLabel.vue +++ b/src/components/settings/TableLabel.vue @@ -1,10 +1,18 @@ @@ -29,5 +37,10 @@ const { short, label } = defineProps({ required: false, default: true, }, + help: { + type: [String, null], + required: false, + default: false, + }, }) diff --git a/src/components/settings/TableValue.vue b/src/components/settings/TableValue.vue index 68e793c..0dae548 100644 --- a/src/components/settings/TableValue.vue +++ b/src/components/settings/TableValue.vue @@ -1,5 +1,8 @@ diff --git a/src/components/settings/form/FormAppPicker.vue b/src/components/settings/form/FormAppPicker.vue new file mode 100644 index 0000000..c1fde4e --- /dev/null +++ b/src/components/settings/form/FormAppPicker.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/src/components/settings/form/FormColorPicker.vue b/src/components/settings/form/FormColorPicker.vue new file mode 100644 index 0000000..554502d --- /dev/null +++ b/src/components/settings/form/FormColorPicker.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/components/settings/form/FormOpener.vue b/src/components/settings/form/FormOpener.vue new file mode 100644 index 0000000..ddae359 --- /dev/null +++ b/src/components/settings/form/FormOpener.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/components/settings/form/FormRange.vue b/src/components/settings/form/FormRange.vue new file mode 100644 index 0000000..cecb5bf --- /dev/null +++ b/src/components/settings/form/FormRange.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/src/components/settings/form/FormSelect.vue b/src/components/settings/form/FormSelect.vue new file mode 100644 index 0000000..4f6fd5a --- /dev/null +++ b/src/components/settings/form/FormSelect.vue @@ -0,0 +1,48 @@ + + + diff --git a/src/components/settings/form/FormSize.vue b/src/components/settings/form/FormSize.vue new file mode 100644 index 0000000..8fd484b --- /dev/null +++ b/src/components/settings/form/FormSize.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/settings/form/FormYesNo.vue b/src/components/settings/form/FormYesNo.vue new file mode 100644 index 0000000..4df509c --- /dev/null +++ b/src/components/settings/form/FormYesNo.vue @@ -0,0 +1,12 @@ + + + diff --git a/src/lib/menu.js b/src/lib/menu.js index a572373..fe35fd4 100644 --- a/src/lib/menu.js +++ b/src/lib/menu.js @@ -1,7 +1,6 @@ const focusActiveApp = (menu) => { window.setTimeout(() => { - const a = menu.querySelector('.side-menu-app.active a') - || menu.querySelector('.side-menu-app a') + const a = menu.querySelector('.side-menu-app.active a') || menu.querySelector('.side-menu-app a') if (a) { a.focus() diff --git a/src/menus/SideMenuWithCategories.vue b/src/menus/SideMenuWithCategories.vue index 2d7d1c6..9fc41f4 100644 --- a/src/menus/SideMenuWithCategories.vue +++ b/src/menus/SideMenuWithCategories.vue @@ -109,11 +109,14 @@ const openerHover = ref(false) const menu = useTemplateRef('menu') const isTouchDevice = window.matchMedia('(pointer: coarse)').matches -watch(() => open, (val) => { - if (val) { - focusActiveApp(menu.value) - } -}) +watch( + () => open, + (val) => { + if (val) { + focusActiveApp(menu.value) + } + }, +) onMounted(async () => { const config = await configStore.getConfig() diff --git a/src/menus/SimpleSideMenu.vue b/src/menus/SimpleSideMenu.vue index 369bd4d..f6a8232 100644 --- a/src/menus/SimpleSideMenu.vue +++ b/src/menus/SimpleSideMenu.vue @@ -30,7 +30,10 @@ along with this program. If not, see . :label="settings.name" :avatar="settings.avatar" /> - + { document.querySelector('html').classList.toggle('side-menu-always-displayed', alwaysDisplayed.value && val.length) }) -watch(() => open, (val) => { - if (val) { - focusActiveApp(menu.value) - } -}) +watch( + () => open, + (val) => { + if (val) { + focusActiveApp(menu.value) + } + }, +) function getFiltredAndSortedApps(items, order, topMenuApps, topSideMenuApps) { const data = [] @@ -148,10 +154,7 @@ onMounted(async () => { avatar.value = config['avatar'] logo.value = config['logo'] useAvatarAsLogo.value = config['use-avatar'] - displayLogo.value = config['display-logo'] && !alwaysDisplayed.value && ( - (!useAvatarAsLogo.value && logo.value) || - (useAvatarAsLogo.value && avatar.value) - ) + displayLogo.value = config['display-logo'] && !alwaysDisplayed.value && ((!useAvatarAsLogo.value && logo.value) || (useAvatarAsLogo.value && avatar.value)) logoLink.value = config['logo-link'] settings.value = config['settings'] diff --git a/src/menus/TopWideMenu.vue b/src/menus/TopWideMenu.vue index d677645..ab2b052 100644 --- a/src/menus/TopWideMenu.vue +++ b/src/menus/TopWideMenu.vue @@ -114,11 +114,14 @@ const openerHover = ref(false) const menu = useTemplateRef('menu') const isTouchDevice = window.matchMedia('(pointer: coarse)').matches -watch(() => open, (val) => { - if (val) { - focusActiveApp(menu.value) - } -}) +watch( + () => open, + (val) => { + if (val) { + focusActiveApp(menu.value) + } + }, +) onMounted(async () => { const config = await configStore.getConfig() diff --git a/src/pages/AdminSettings.vue b/src/pages/AdminSettings.vue index 4c57ac9..0d63b52 100644 --- a/src/pages/AdminSettings.vue +++ b/src/pages/AdminSettings.vue @@ -1,92 +1,505 @@ diff --git a/src/scss/admin.scss b/src/scss/admin.scss index fafdd14..d43e70a 100644 --- a/src/scss/admin.scss +++ b/src/scss/admin.scss @@ -114,7 +114,7 @@ .side-menu-setting-table { display: table; width: 100%; - padding: 10px; + padding: 20px; } .side-menu-setting-row { @@ -225,9 +225,9 @@ } .side-menu-setting { - padding: 10px; + padding: 20px; display: flex; - gap: 12px; + gap: 5px; } .side-menu-setting-color-picker { diff --git a/src/scss/menu.scss b/src/scss/menu.scss index c1dd6cf..cecd2b3 100644 --- a/src/scss/menu.scss +++ b/src/scss/menu.scss @@ -66,7 +66,8 @@ } } - &.side-menu-big, &.side-menu-with-categories { + &.side-menu-big, + &.side-menu-with-categories { height: auto; } } @@ -225,7 +226,8 @@ } } -.side-menu-big, .side-menu-with-categories { +.side-menu-big, +.side-menu-with-categories { .side-menu-apps-list { height: auto; position: static; @@ -284,7 +286,6 @@ stroke: var(--side-menu-text-color, #fff); } - .side-menu-always-displayed { body { width: calc(100% - 50px) !important; diff --git a/src/store/config.js b/src/store/config.js index 29c5693..22be6ab 100644 --- a/src/store/config.js +++ b/src/store/config.js @@ -5,6 +5,7 @@ import { generateUrl } from '@nextcloud/router' export const useConfigStore = defineStore('config', () => { const config = ref(null) + const appConfig = ref(null) async function getConfig() { if (config.value !== null) { @@ -16,7 +17,18 @@ export const useConfigStore = defineStore('config', () => { return config.value } + async function getAppConfig() { + if (appConfig.value !== null) { + return appConfig.value + } + + appConfig.value = await axios.get(generateUrl('/apps/side_menu/admin/config')).then((response) => response.data) + + return appConfig.value + } + return { getConfig, + getAppConfig, } }) From 8474f0945bdd15f1acfe28e0d43563f17a9be044 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Thu, 10 Apr 2025 20:02:02 +0200 Subject: [PATCH 123/228] fix linter issues --- src/components/AppSearch.vue | 4 +- src/components/settings/SectionTitle.vue | 14 +- src/components/settings/TableLabel.vue | 2 +- .../settings/form/FormAppPicker.vue | 52 ++++---- .../settings/form/FormColorPicker.vue | 2 +- src/components/settings/form/FormOpener.vue | 2 +- src/components/settings/form/FormRange.vue | 36 ++--- src/components/settings/form/FormSelect.vue | 11 +- src/components/settings/form/FormSize.vue | 2 +- src/components/settings/form/FormYesNo.vue | 2 +- src/menus/MenuContainer.vue | 17 --- src/menus/SideMenuWithCategories.vue | 2 +- src/menus/SimpleSideMenu.vue | 6 +- src/menus/TopWideMenu.vue | 2 +- src/pages/AdminSettings.vue | 126 +++++++++++------- 15 files changed, 148 insertions(+), 132 deletions(-) diff --git a/src/components/AppSearch.vue b/src/components/AppSearch.vue index f7275b4..6f70437 100644 --- a/src/components/AppSearch.vue +++ b/src/components/AppSearch.vue @@ -17,13 +17,13 @@ along with this program. If not, see . diff --git a/src/components/settings/SectionTitle.vue b/src/components/settings/SectionTitle.vue index c17dc45..a88a48b 100644 --- a/src/components/settings/SectionTitle.vue +++ b/src/components/settings/SectionTitle.vue @@ -2,13 +2,6 @@

{{ t('side_menu', label) }}

- - + + diff --git a/src/components/settings/TableLabel.vue b/src/components/settings/TableLabel.vue index 0e5a5a6..0bc5fe5 100644 --- a/src/components/settings/TableLabel.vue +++ b/src/components/settings/TableLabel.vue @@ -40,7 +40,7 @@ const { short, label } = defineProps({ help: { type: [String, null], required: false, - default: false, + default: null, }, }) diff --git a/src/components/settings/form/FormAppPicker.vue b/src/components/settings/form/FormAppPicker.vue index c1fde4e..4a9c712 100644 --- a/src/components/settings/form/FormAppPicker.vue +++ b/src/components/settings/form/FormAppPicker.vue @@ -1,8 +1,8 @@ + + - - diff --git a/src/components/settings/form/FormColorPicker.vue b/src/components/settings/form/FormColorPicker.vue index 554502d..e2ab147 100644 --- a/src/components/settings/form/FormColorPicker.vue +++ b/src/components/settings/form/FormColorPicker.vue @@ -13,5 +13,5 @@ diff --git a/src/components/settings/form/FormOpener.vue b/src/components/settings/form/FormOpener.vue index ddae359..f0b53e5 100644 --- a/src/components/settings/form/FormOpener.vue +++ b/src/components/settings/form/FormOpener.vue @@ -8,7 +8,7 @@ + + diff --git a/src/components/settings/form/FormSelect.vue b/src/components/settings/form/FormSelect.vue index 4f6fd5a..6c54d17 100644 --- a/src/components/settings/form/FormSelect.vue +++ b/src/components/settings/form/FormSelect.vue @@ -1,9 +1,14 @@