diff --git a/.github/AUTHORS.txt b/.github/AUTHORS.txt index 42fd13c7..e89054a5 100644 --- a/.github/AUTHORS.txt +++ b/.github/AUTHORS.txt @@ -1,27 +1,29 @@ Alicia - 1 commits Begin - 1 commits +David - 1 commits DeepSource - 1 commits Devin - 1 commits FormatToday <616099456@qq.com> - 1 commits +Rune - 1 commits Ryan - 1 commits deepsource-io[bot] - 1 commits liss-bot <87835202+liss-bot@users.noreply.github.com> - 1 commits Dan - 2 commits ᗪєνιη <υн> - 2 commits -Alicia - 3 commits UrekD - 3 commits Niklas - 4 commits Erik - 6 commits liss-bot - 6 commits -repo-visualizer - 6 commits -snyk-bot - 8 commits +Alicia - 8 commits +repo-visualizer - 8 commits +snyk-bot - 9 commits Alicia - 10 commits -snyk-bot - 13 commits EVOTk <45015615+EVOTk@users.noreply.github.com> - 14 commits +snyk-bot - 14 commits github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - 16 commits -liss-bot - 17 commits +liss-bot - 21 commits Alicia - 25 commits -Lissy93 - 67 commits -Lissy93 - 172 commits -Alicia - 242 commits -Alicia - 954 commits \ No newline at end of file +Lissy93 - 70 commits +Lissy93 - 186 commits +Alicia - 255 commits +Alicia - 1004 commits \ No newline at end of file diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index e9d31581..47e586a2 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## ✨ 1.8.8 - Improved Item Targets [PR #292](https://github.com/Lissy93/dashy/pull/292) +- Adds support for `_top` and `_parent` anchor targets on items, Re: #289 +- Adds `appConfig.defaultOpeningMethod` option to specify default target +- Adds new icons to show items opening method on hover +- Refactors target checking, updates item target docs and schema + ## ⚡️ 1.8.7 - Bug Fixes and Improvements [PR #273](https://github.com/Lissy93/dashy/pull/273) - Clean URLs without the hash, now using history-mode routing - New initial main example conf.yml diff --git a/.github/workflows/issue-spam-control.yml b/.github/workflows/issue-spam-control.yml index 65de503c..1beb581b 100644 --- a/.github/workflows/issue-spam-control.yml +++ b/.github/workflows/issue-spam-control.yml @@ -10,6 +10,7 @@ jobs: ${{ ! contains( github.event.issue.labels.*.name, '📌 Keep Open') && ! contains( github.event.issue.labels.*.name, '🌈 Feedback') && + ! contains( github.event.issue.labels.*.name, '💯 Showcase') && github.event.comment.author_association != 'CONTRIBUTOR' }} runs-on: ubuntu-latest @@ -21,7 +22,7 @@ jobs: token: ${{ secrets.BOT_GITHUB_TOKEN }} message: | Welcome to Dashy 👋 - It's great to have you here, but unfortunately your ticket has been closed to prevent spam and low quality issues. Please ensure the following criteria are met, before reopening this issue. + It's great to have you here, but unfortunately your ticket has been closed to prevent spam. Before reopening this issue, please ensure the following criteria are met. Issues are sometimes closed when users: - Have only recently joined GitHub @@ -33,4 +34,4 @@ jobs: - You have checked the documentation for an existing solution - You have completed the relevant sections in the Issue template - Once you have verified the above standards are met, you may reopen this issue. + Once you have verified the above standards are met, you may reopen this issue. Sorry for any inconvenience caused, I'm just a bot, and sometimes make mistakes 🤖 diff --git a/README.md b/README.md index 06e2e18f..23030554 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,9 @@

+| 👉 PSA: Want Free Swag? [Dashy is participating in Hacktoberfest 2021!](https://github.com/Lissy93/dashy/discussions/281) | +|-| + ## Features 🌈 - 🔎 Instant search by name, domain and tags + customizable hotkeys & keyboard shortcuts @@ -301,6 +304,9 @@ One of the primary purposes of Dashy is to make launching commonly used apps and - `newtab` - The app will be launched in a new tab - `modal` - Launch app in a resizable/ movable popup modal on the current page - `workspace` - Changes to Workspace view, and launches app +- `top` - Opens in the top-most browsing context, useful if your accessing Dashy through an iframe + +You can also set the default opening method, which will be applied to all items that don't have a specified target, using `appConfig.defaultOpeningMethod`, to one of the above values. Even if the target is not set (or is set to `sametab`), you can still launch any given app in an alternative method: Alt + Click will open the modal, and Ctrl + Click will open in a new tab. You can also right-click on any item to see all options (as seen in the screenshot below). This custom context menu can be disabled by setting `appConfig.disableContextMenu: true`. @@ -442,6 +448,7 @@ Dashy supports multiple languages and locales. When available, you're language s - 🇳🇱 **Dutch**: `nl` - Contributed by **[@evroon](https://github.com/evroon)** - 🇲🇫 **French**: `fr` - Contributed by **[@EVOTk](https://github.com/EVOTk)** - 🇩🇪 **German**: `de` - Contributed by **[@Niklashere](https://github.com/Niklashere)** +- 🇳🇴 **Norwegian Bokmål**: `nb` - Contributed by **[@rubjo](https://github.com/rubjo)** - 🇪🇸 **Spanish**: `es` - Contributed by **[@lu4t](https://github.com/lu4t)** - 🇸🇮 **Slovenian**: `sl` - Contributed by **[@UrekD](https://github.com/UrekD)** - 🇮🇹 **Italian**: `it` - Machine Translated *(awaiting human review)* @@ -450,9 +457,10 @@ Dashy supports multiple languages and locales. When available, you're language s - 🇦🇪 **Arabic**: `ar` - Contributed by Anon - 🇮🇳 **Hindi**: `hi` - Contributed by Anon - 🇯🇵 **Japanese**: `ja` - Contributed by Anon +- 🇵🇱 **Polish**: `pl` - Contributed by **[@skaarj1989](https://github.com/skaarj1989)** #### Add your Language -I would love for Dashy to be available to everyone, without language being a barrier to entry for non-native English speakers. If you have a few minutes to sapir, you're help with translating it would be very much appreciated. +I would love for Dashy to be available to everyone, without language being a barrier to entry for non-native English speakers. If you have a few minutes to spare, you're help with translating it would be very much appreciated. It's quite a quick task, all text is in [a single JSON file](https://github.com/Lissy93/dashy/tree/master/src/assets/locales), and you don't have to translate it all. For more info, see the [Adding a New Language Docs](./docs/multi-language-support.md#adding-a-new-language), and feel free to reach out if you need any support. **[⬆️ Back to Top](#dashy)** @@ -646,7 +654,7 @@ For a full breakdown of each change, you can view the [Changelog](https://github - 💻 [Management](/docs/management.md) - Managing your app, updating, security, web server configuration, etc - 🚒 [Troubleshooting](/docs/troubleshooting.md) - Common errors and problems, and how to fix them -#### Development and Contributing +#### Development and Contributing - 🧱 [Developing](/docs/developing.md) - Running Dashy development server locally, and general workflow - 🛎️ [Development Guides](/docs/development-guides.md) - Common development tasks, to help new contributors - 💖 [Contributing](/docs/contributing.md) - How to contribute to Dashy diff --git a/docs/alternate-views.md b/docs/alternate-views.md index 29dc032c..2417316a 100644 --- a/docs/alternate-views.md +++ b/docs/alternate-views.md @@ -37,9 +37,12 @@ Dashy supports several different ways to launch your apps. The default opening m - `sametab` - The app will be launched in the current tab - `newtab` - The app will be launched in a new tab +- `top` - Opens in the top-most browsing context, useful if your accessing Dashy through an iframe - `modal` - Launch app in a resizable/ movable popup modal on the current page - `workspace` - Changes to Workspace view, and launches app +You can also set the default opening method, which will be applied to all items that don't have a specified target, using `appConfig.defaultOpeningMethod`, to one of the above values. + Even if the target is not set (or is set to `sametab`), you can still launch any given app in an alternative method: Alt + Click will open the modal, and Ctrl + Click will open in a new tab. You can also right-click on any item to see all options (as seen in the screenshot below). This custom context menu can be disabled by setting `appConfig.disableContextMenu: true`.

diff --git a/docs/assets/CONTRIBUTORS.svg b/docs/assets/CONTRIBUTORS.svg index 556007b8..a569aebe 100644 --- a/docs/assets/CONTRIBUTORS.svg +++ b/docs/assets/CONTRIBUTORS.svg @@ -6,11 +6,11 @@ - - - - + + + + @@ -19,15 +19,21 @@ - + + + + - + - + + + + - + \ No newline at end of file diff --git a/docs/assets/repo-visualization.svg b/docs/assets/repo-visualization.svg index 230c683e..dc21f215 100644 --- a/docs/assets/repo-visualization.svg +++ b/docs/assets/repo-visualization.svg @@ -1 +1 @@ -viewsviewsutilsutilsstylesstylescomponentscomponentsassetsassetsWorkspaceWorkspaceSettingsSettingsPageStrcturePageStrctureMinimalViewMinimalViewLinkItemsLinkItemsFormElementsFormElementsConfigurationConfigurationlocaleslocalesinterface-iconsinterface-iconsHome.vueHome.vueHome.vueLogin.vueLogin.vueLogin.vueMinimal.vueMinimal.vueMinimal.vueemojis.jsonemojis.jsonemojis.jsonConfigSche...ConfigSche...ConfigSche...defaults.jsdefaults.jsdefaults.jscolor-them...color-them...color-them...CustomThe...CustomThe...CustomThe...SearchBa...SearchBa...SearchBa...Item.vueItem.vueItem.vueItemIcon...ItemIcon...ItemIcon...ConfigCon...ConfigCon...ConfigCon...JsonEdito...JsonEdito...JsonEdito...CloudBac...CloudBac...CloudBac...hi.jsonhi.jsonhi.jsonru.jsonru.jsonru.jsonar.jsonar.jsonar.jsonja.jsonja.jsonja.jsonfr.jsonfr.jsonfr.jsones.jsones.jsones.jsonpt.jsonpt.jsonpt.jsonit.jsonit.jsonit.json.js.json.scss.svg.vueeach dot sized by file size \ No newline at end of file +viewsviewsutilsutilsstylesstylescomponentscomponentsassetsassetsWorkspaceWorkspaceSettingsSettingsPageStrcturePageStrctureMinimalViewMinimalViewLinkItemsLinkItemsFormElementsFormElementsConfigurationConfigurationlocaleslocalesinterface-iconsinterface-iconsHome.vueHome.vueHome.vueLogin.vueLogin.vueLogin.vueMinimal.vueMinimal.vueMinimal.vueemojis.jsonemojis.jsonemojis.jsonConfigSche...ConfigSche...ConfigSche...defaults.jsdefaults.jsdefaults.jscolor-them...color-them...color-them...CustomThe...CustomThe...CustomThe...SearchBa...SearchBa...SearchBa...Item.vueItem.vueItem.vueItemIcon...ItemIcon...ItemIcon...ConfigCon...ConfigCon...ConfigCon...JsonEdito...JsonEdito...JsonEdito...CloudBac...CloudBac...CloudBac...hi.jsonhi.jsonhi.jsonru.jsonru.jsonru.jsonar.jsonar.jsonar.jsonja.jsonja.jsonja.jsonfr.jsonfr.jsonfr.jsones.jsones.jsones.jsonpt.jsonpt.jsonpt.jsonit.jsonit.jsonit.json.js.json.scss.svg.vueeach dot sized by file size \ No newline at end of file diff --git a/docs/configuring.md b/docs/configuring.md index ebe39c9b..5d13fbe5 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -74,6 +74,7 @@ Tips: --- | --- | --- | --- **`language`** | `string` | _Optional_ | The 2 (or 4-digit) [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) for your language, e.g. `en` or `en-GB`. This must be a language that the app has already been [translated](https://github.com/Lissy93/dashy/tree/master/src/assets/locales) into. If your language is unavailable, Dashy will fallback to English. By default Dashy will attempt to auto-detect your language, although this may not work on some privacy browsers. **`startingView`** | `enum` | _Optional_ | Which page to load by default, and on the base page or domain root. You can still switch to different views from within the UI. Can be either `default`, `minimal` or `workspace`. Defaults to `default` +**`defaultOpeningMethod`** | `enum` | _Optional_ | The default opening method for items, if no `target` is specified for a given item. Can be either `newtab`, `sametab`, `top`, `parent`, `modal` or `workspace`. Defaults to `newtab` **`statusCheck`** | `boolean` | _Optional_ | When set to `true`, Dashy will ping each of your services and display their status as a dot next to each item. This can be overridden by setting `statusCheck` under each item. Defaults to `false` **`statusCheckInterval`** | `boolean` | _Optional_ | The number of seconds between checks. If set to `0` then service will only be checked on initial page load, which is usually the desired functionality. If value is less than `10` you may experience a hit in performance. Defaults to `0` **`webSearch`** | `object` | _Optional_ | Configuration options for the web search feature, set your default search engine, opening method or disable web search. See [`webSearch`](#appconfigwebsearch-optional) @@ -181,7 +182,7 @@ For more info, see the **[Authentication Docs](/docs/authentication.md)** **`description`** | `string` | _Optional_ | Additional info about an item, which is shown in the tooltip on hover, or visible on large tiles **`url`** | `string` | Required | The URL / location of web address for when the item is clicked **`icon`** | `string` | _Optional_ | The icon for a given item. Can be a font-awesome icon, favicon, remote URL or local URL. See [`item.icon`](#sectionicon-and-sectionitemicon) -**`target`** | `string` | _Optional_ | The opening method for when the item is clicked, either `newtab`, `sametab`, `modal` or `workspace`. Where `newtab` will open the link in a new tab, `sametab` will open it in the current tab, and `modal` will open a pop-up modal with the content displayed within that iframe. Note that for the iframe to load, you must have set the CORS headers to either allow `*` ot allow the domain that you are hosting Dashy on, for some websites and self-hosted services, this is already set. +**`target`** | `string` | _Optional_ | The opening method for when the item is clicked, either `newtab`, `sametab`, `top`, `parent`, `modal` or `workspace`. Where `newtab` will open the link in a new tab, `sametab` will open it in the current tab, and `modal` will open a pop-up modal and `workspace` will open in the Workspace view. Defaults to `newtab` **`hotkey`** | `number` | _Optional_ | Give frequently opened applications a numeric hotkey, between `0 - 9`. You can then just press that key to launch that application. **`tags`** | `string[]` | _Optional_ | A list of tags, which can be used for improved search **`statusCheck`** | `boolean` | _Optional_ | When set to `true`, Dashy will ping the URL associated with the current service, and display its status as a dot next to the item. The value here will override `appConfig.statusCheck` so you can turn off or on checks for a given service. Defaults to `appConfig.statusCheck`, falls back to `false` diff --git a/docs/credits.md b/docs/credits.md index 8e10c932..ce791c13 100644 --- a/docs/credits.md +++ b/docs/credits.md @@ -32,6 +32,13 @@ EVOTk + + + liss-bot +
+ Alicia Bot +
+ evroon @@ -46,13 +53,6 @@ Snyk Bot - - - liss-bot -
- Alicia Bot -
- UrekD @@ -96,6 +96,14 @@ FormatToday + + + rubjo +
+ Rubjo +
+ + turnrye diff --git a/docs/searching.md b/docs/searching.md index 870618d1..e699f97d 100644 --- a/docs/searching.md +++ b/docs/searching.md @@ -7,7 +7,7 @@ One of the primary purposes of Dashy is to allow you to quickly find and launch You can navigate through your items or search results using the keyboard. You can use Tab to cycle through results, and Shift + Tab to go backwards. Or use the arrow keys, , , and . ## Launching Apps -You can launch a elected app by hitting Enter. This will open the app using your default opening method, specified in `target` (either `newtab`, `sametab`, `modal` or `workspace`). You can also use Alt + Enter to open the app in a pop-up modal, or Ctrl + Enter to open it in a new tab. For all available opening methods, just right-click on an item, to bring up the context menu. +You can launch a elected app by hitting Enter. This will open the app using your default opening method, specified in `target` (either `newtab`, `sametab`, `modal`, `top` or `workspace`). You can also use Alt + Enter to open the app in a pop-up modal, or Ctrl + Enter to open it in a new tab. For all available opening methods, just right-click on an item, to bring up the context menu. ## Tags By default, items are filtered by the `title` attribute, as well as the hostname (extracted from `url`), the `provider` and `description`. If you need to find results based on text which isn't included in these attributes, then you can add `tags` to a given item. diff --git a/docs/showcase.md b/docs/showcase.md index b25e4b11..52f82d42 100644 --- a/docs/showcase.md +++ b/docs/showcase.md @@ -23,6 +23,16 @@ --- +### HomeLAb 3.0 + +> By [@skoogee](https://github.com/skoogee) (http://zhrn.cc) + +> Dashy, is the most complete dashboard I ever tried, has all the features, and it sets itself apart from the rest. It is my default homepage now. I am thankful to the developer @Lissy93 for sharing such a wonderful creation. + +[![screenshot-12-skoogee-homelab-3](https://i.ibb.co/Sv7cxcg/12-skoogee-homelab-3.png)](https://ibb.co/album/ynSwzm) + +--- + ### NAS Home Dashboard > By [@cerealconyogurt](https://github.com/cerealconyogurt) diff --git a/package.json b/package.json index 4ba488b7..127866a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Dashy", - "version": "1.8.7", + "version": "1.8.8", "license": "MIT", "main": "server", "scripts": { @@ -20,7 +20,7 @@ "@sentry/tracing": "^6.13.1", "@sentry/vue": "^6.13.1", "ajv": "^8.6.3", - "axios": "^0.21.4", + "axios": "^0.22.0", "body-parser": "^1.19.0", "connect": "^3.7.0", "connect-history-api-fallback": "^1.6.0", diff --git a/src/assets/interface-icons/open-parent.svg b/src/assets/interface-icons/open-parent.svg new file mode 100644 index 00000000..09f69591 --- /dev/null +++ b/src/assets/interface-icons/open-parent.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/interface-icons/open-top.svg b/src/assets/interface-icons/open-top.svg new file mode 100644 index 00000000..b93ecf0d --- /dev/null +++ b/src/assets/interface-icons/open-top.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/interface-icons/open-workspace.svg b/src/assets/interface-icons/open-workspace.svg index b0a186ca..6c0590d8 100644 --- a/src/assets/interface-icons/open-workspace.svg +++ b/src/assets/interface-icons/open-workspace.svg @@ -1,20 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/interface-icons/unknown-icon.svg b/src/assets/interface-icons/unknown-icon.svg new file mode 100644 index 00000000..2a3a5c66 --- /dev/null +++ b/src/assets/interface-icons/unknown-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/locales/nb.json b/src/assets/locales/nb.json new file mode 100644 index 00000000..305b4c04 --- /dev/null +++ b/src/assets/locales/nb.json @@ -0,0 +1,172 @@ +{ + "home": { + "no-results": "Ingen søkeresultater", + "no-data": "Ingen data konfigurert" + }, + "search": { + "search-label": "Søk", + "search-placeholder": "Begynn å skrive for å filtrere", + "clear-search-tooltip": "Fjern søk", + "enter-to-search-web": "Trykk enter for å søke på nettet" + }, + "login": { + "title": "Dashy", + "username-label": "Brukernavn", + "password-label": "Passord", + "login-button": "Logg inn", + "remember-me-label": "Husk meg", + "remember-me-never": "Aldri", + "remember-me-hour": "4 timer", + "remember-me-day": "1 dag", + "remember-me-week": "1 uke", + "error-missing-username": "Mangler brukernavn", + "error-missing-password": "Manglende passord", + "error-incorrect-username": "Bruker ikke funnet", + "error-incorrect-password": "Feil passord", + "success-message": "Logger på...", + "logout-message": "Logget ut", + "already-logged-in-title": "Allerede logget inn", + "already-logged-in-text": "Du er logget inn som", + "continue-to-dashboard": "Fortsett til dashbordet", + "log-out-button": "Logg ut", + "continue-guest-button": "Fortsett som gjest" + }, + "config": { + "main-tab": "Hovedmeny", + "view-config-tab": "Vis konfigurering", + "edit-config-tab": "Rediger konfigurering", + "custom-css-tab": "Egendefinerte stiler", + "heading": "Konfigurasjonsalternativer", + "download-config-button": "Last ned konfigurasjon", + "edit-config-button": "Rediger konfigurering", + "edit-css-button": "Rediger tilpasset CSS", + "cloud-sync-button": "Aktiver skysynkronisering", + "edit-cloud-sync-button": "Rediger skysynkronisering", + "rebuild-app-button": "Bygg program", + "change-language-button": "Endre appspråk", + "reset-settings-button": "Tilbakestill lokale innstillinger", + "app-info-button": "Appinfo", + "backup-note": "Det anbefales å ta en sikkerhetskopi av konfigurasjonen din før du gjør endringer.", + "reset-config-msg-l1": "Dette fjerner alle brukerinnstillinger fra lokal lagring, men påvirker ikke din 'conf.yml' -fil.", + "reset-config-msg-l2": "Du bør først ta sikkerhetskopi av eventuelle endringer du har gjort lokalt, hvis du vil bruke dem i fremtiden.", + "reset-config-msg-l3": "Er du sikker på at du vil fortsette?", + "data-cleared-msg": "Data slettet vellykket", + "actions-label": "Handlinger", + "copy-config-label": "Kopier konfigurasjon", + "data-copied-msg": "Konfig er kopiert til utklippstavlen", + "reset-config-label": "Tilbakestill konfigurasjon", + "css-save-btn": "Lagre endringer", + "css-note-label": "Merk", + "css-note-l1": "Du må oppdatere siden for at endringene dine skal tre i kraft.", + "css-note-l2": "Overstyring av stiler lagres bare lokalt, så det anbefales å lage en kopi av CSS.", + "css-note-l3": "For å fjerne alle egendefinerte stiler, slett innholdet og trykk Lagre endringer" + }, + "alternate-views": { + "alternate-view-heading": "Bytt visning", + "default": "Standard", + "workspace": "Workspace", + "minimal": "Minimal" + }, + "settings": { + "theme-label": "Tema", + "layout-label": "Layout", + "layout-auto": "Auto", + "layout-horizontal": "Horisontal", + "layout-vertical": "Vertikal", + "item-size-label": "Enhetsstørrelse", + "item-size-small": "Small", + "item-size-medium": "Medium", + "item-size-large": "Large", + "config-launcher-label": "Konfig", + "config-launcher-tooltip": "Oppdater konfigurasjon", + "sign-out-tooltip": "Logg av", + "sign-in-tooltip": "Logg inn", + "sign-in-welcome": "Hei {brukernavn}!" + }, + "updates": { + "app-version-note": "Dashy-versjon", + "up-to-date": "Oppdatert", + "out-of-date": "Oppdatering tilgjengelig", + "unsupported-version-l1": "Du bruker en ikke-støttet versjon av Dashy", + "unsupported-version-l2": "For den beste opplevelsen og de siste sikkerhetsoppdateringene, vennligst oppdater til" + }, + "language-switcher": { + "title": "Endre applikasjonsspråk", + "dropdown-label": "Velg et språk", + "save-button": "Lagre", + "success-msg": "Språk oppdatert til" + }, + "theme-maker": { + "title": "Temakonfigurator", + "export-button": "Eksporter tilpassede variabler", + "reset-button": "Tilbakestill stiler for", + "show-all-button": "Vis alle variabler", + "save-button": "Lagre", + "cancel-button": "Avbryt", + "saved-toast": "{theme} Oppdatert vellykket", + "copied-toast": "Temadata for {theme} kopiert til utklippstavlen", + "reset-toast": "Egendefinerte farger for {theme} fjernet" + }, + "config-editor": { + "save-location-label": "Lagre beliggenhet", + "location-local-label": "Søk lokalt", + "location-disk-label": "Skriv endringer i konfigurasjonsfil", + "save-button": "Lagre endringer", + "valid-label": "Konfigurasjon er gyldig", + "status-success-msg": "Oppgaven fullført", + "status-fail-msg": "Oppgaven mislyktes", + "success-msg-disk": "Konfigurasjonsfil skrevet til disk med hell", + "success-msg-local": "Lokale endringer er lagret", + "success-note-l1": "Appen bør bygge om automatisk.", + "success-note-l2": "Dette kan ta opptil et minutt.", + "success-note-l3": "Du må oppdatere siden for at endringene skal tre i kraft.", + "error-msg-save-mode": "Velg en lagringsmodus: lokal eller fil", + "error-msg-cannot-save": "Det oppsto en feil under konfigurering", + "error-msg-bad-json": "Feil i JSON, muligens feilformet", + "warning-msg-validation": "Valideringsadvarsel", + "not-admin-note": "Du kan ikke skrive endret til disk, fordi du ikke er logget inn som admin" + }, + "app-rebuild": { + "title": "Ombygg applikasjon", + "rebuild-note-l1": "En ombygging er nødvendig for at endringer skrevet i conf.yml-filen skal tre i kraft.", + "rebuild-note-l2": "Dette bør skje automatisk, men hvis det ikke har blitt gjort, kan du manuelt utløse det her.", + "rebuild-note-l3": "Dette er ikke nødvendig for endringer som er lagret lokalt.", + "rebuild-button": "Start Build", + "rebuilding-status-1": "Building ...", + "rebuilding-status-2": "Dette kan ta noen minutter", + "error-permission": "Du har ikke tillatelse til å utløse denne handlingen", + "success-msg": "Byggingen er fullført", + "fail-msg": "Byggoperasjonen mislyktes", + "reload-note": "En sideinnlasting er nå nødvendig for at endringer skal tre i kraft", + "reload-button": "Last siden på nytt" + }, + "cloud-sync": { + "title": "Sikkerhetskopiering & gjenoppretting", + "intro-l1": "Sikkerhetskopiering og gjenoppretting er en valgfri funksjon, som lar deg laste opp konfigurasjonen din til internett og deretter gjenopprette den på en hvilken som helst annen enhet eller forekomst av Dashy.", + "intro-l2": "Alle data er helt ende-til-ende-kryptert med AES, og bruker passordet ditt som nøkkelen.", + "intro-l3": "For mer informasjon, se", + "backup-title-setup": "Lag en sikkerhetskopi", + "backup-title-update": "Oppdater sikkerhetskopi", + "password-label-setup": "Velg et passord", + "password-label-update": "Skriv inn passordet ditt", + "backup-button-setup": "Sikkerhetskopiering", + "backup-button-update": "Oppdater sikkerhetskopi", + "backup-id-label": "Din sikkerhetskopi-ID", + "backup-id-note": "Dette brukes til å gjenopprette fra sikkerhetskopier senere. Så behold det, sammen med passordet ditt et trygt sted.", + "restore-title": "Gjenopprett en sikkerhetskopi", + "restore-id-label": "Gjenopprett ID", + "restore-password-label": "Passord", + "restore-button": "Gjenopprett", + "backup-missing-password": "Manglende passord", + "backup-error-unknown": "Kan ikke behandle forespørselen", + "backup-error-password": "Feil passord. Skriv inn ditt nåværende passord.", + "backup-success-msg": "Fullført vellykket", + "restore-success-msg": "Konfigurasjon gjenopprettet vellykket" + }, + "menu": { + "sametab": "Åpne i nåværende fane", + "newtab": "Åpne i ny fane", + "modal": "Åpne i popup-modus", + "workspace": "Åpne i Workspace-visning" + } +} \ No newline at end of file diff --git a/src/assets/locales/pl.json b/src/assets/locales/pl.json new file mode 100644 index 00000000..4523fde1 --- /dev/null +++ b/src/assets/locales/pl.json @@ -0,0 +1,172 @@ +{ + "home": { + "no-results": "Brak wyników", + "no-data": "Brak danych" + }, + "search": { + "search-label": "Wyszukaj", + "search-placeholder": "Zacznij pisać aby przefiltrować", + "clear-search-tooltip": "Wyczyść", + "enter-to-search-web": "Naciśnij ENTER aby przeszukać internet" + }, + "login": { + "title": "Dashy", + "username-label": "Użytkownik", + "password-label": "Hasło", + "login-button": "Zaloguj", + "remember-me-label": "Zapamiętaj mnie", + "remember-me-never": "Nigdy", + "remember-me-hour": "4 godziny", + "remember-me-day": "Dzień", + "remember-me-week": "Tydzień", + "error-missing-username": "Nie podano nazwy użytkownika", + "error-missing-password": "Nie podano hasła", + "error-incorrect-username": "Nie znaleziono użytkownika", + "error-incorrect-password": "Niepoprawne hasło", + "success-message": "Zalogowano...", + "logout-message": "Wylogowano", + "already-logged-in-title": "Jesteś już zalogowany", + "already-logged-in-text": "Zalogowano jako", + "proceed-to-dashboard": "Przejdź do panelu", + "log-out-button": "Wyloguj", + "proceed-guest-button": "Kontynuuj jako gość" + }, + "config": { + "main-tab": "Menu główne", + "view-config-tab": "Wyświetl konfigurację", + "edit-config-tab": "Edytuj konfigurację", + "custom-css-tab": "Niestandardowy styl", + "heading": "Opcje konfiguracji", + "download-config-button": "Pobierz plik konfiguracji", + "edit-config-button": "Edytuj konfigurację", + "edit-css-button": "Edytuj styl CSS", + "cloud-sync-button": "Ustawienia chmury", + "edit-cloud-sync-button": "Ustawienia chmury", + "rebuild-app-button": "Przebuduj aplikację", + "change-language-button": "Zmień język", + "reset-settings-button": "Zresetuj pamięć podręczną", + "app-info-button": "Informacje o aplikacji", + "backup-note": "Przed dokonaniem zmian zaleca się zapisanie kopii zapasowej konfiguracji.", + "reset-config-msg-l1": "Zostaną usunięte wszystkie ustawienia zapisane w pamięci podręcznej (Nie dotyczy pliku 'conf.yml'). ", + "reset-config-msg-l2": "Zrób kopię zapasową jeśli obecne ustawienia są ważne.", + "reset-config-msg-l3": "Czy na pewno chcesz kontynuować?", + "data-cleared-msg": "Dane wyczyszczone pomyślnie", + "actions-label": "Akcje", + "copy-config-label": "Kopia konfiguracji", + "data-copied-msg": "Konfiguracja skopiowana do schowka", + "reset-config-label": "Zresetuj konfigurację", + "css-save-btn": "Zapisz zmiany", + "css-note-label": "Informacja", + "css-note-l1": "Po dokonaniu zmian konieczne będzie odświeżenie strony.", + "css-note-l2": "Nadpisane style przechowywane są w pamięci podręcznej, zaleca się więc wykonanie kopii stylu CSS.", + "css-note-l3": "Aby usunąć niestandardowe style, wyczyść zawartość pola tekstowego i naciśnij Zapisz zmiany" + }, + "alternate-views": { + "alternate-view-heading": "Zmień widok", + "default": "Domyślny", + "workspace": "Obszar roboczy", + "minimal": "Minimalny" + }, + "settings": { + "theme-label": "Motyw", + "layout-label": "Układ", + "layout-auto": "Automatyczny", + "layout-horizontal": "Poziomy", + "layout-vertical": "Pionowy", + "item-size-label": "Rozmiar elementu", + "item-size-small": "Mały", + "item-size-medium": "Średni", + "item-size-large": "Duży", + "config-launcher-label": "Konfiguracja", + "config-launcher-tooltip": "Przejdź do ustawień", + "sign-out-tooltip": "Wyloguj", + "sign-in-tooltip": "Zaloguj", + "sign-in-welcome": "Cześć {username}!" + }, + "updates": { + "app-version-note": "wersja Dashy", + "up-to-date": "Aktualna", + "out-of-date": "Dostępna aktualizacja", + "unsupported-version-l1": "Używasz niewspieranej wersji Dashy", + "unsupported-version-l2": "Zaleca się zaktualizowanie do" + }, + "language-switcher": { + "title": "Zmień język", + "dropdown-label": "Wybierz język", + "save-button": "Zapisz", + "success-msg": "Język zmieniony na" + }, + "theme-maker": { + "title": "Konfigurator motywu", + "export-button": "Eksportuj zmienne", + "reset-button": " Zresetuj styl", + "show-all-button": "Pokaż wszystkie zmienne", + "save-button": "Zapisz", + "cancel-button": "Anuluj", + "saved-toast": "Pomyślnie zaktualizowano {theme}", + "copied-toast": "Dane motywu {theme} zostały skopiowane do schowka", + "reset-toast": "Niestandardowe kolory dla {theme} usunięte" + }, + "config-editor": { + "save-location-label": "Lokalizacja zapisu", + "location-local-label": "Pamięć podręczna", + "location-disk-label": "Plik na dysku", + "save-button": "Zapisz", + "valid-label": "Konfiguracja poprawna", + "status-success-msg": "Zadanie ukończone", + "status-fail-msg": "Zadanie nie powiodło się", + "success-msg-disk": "Pomyślnie zapisano na dysku", + "success-msg-local": "Pomyślnie zapisano w pamięci podręcznej", + "success-note-l1": "Aplikacja powinna automatycznie się przebudować.", + "success-note-l2": "Może to zająć około minuty.", + "success-note-l3": "Będzie konieczne odświeżenie strony", + "error-msg-save-mode": "Proszę wybrać pomiędzy pamięcią podręczną lub plikiem na dysku", + "error-msg-cannot-save": "Wystąpił błąd podczas zapisywania", + "error-msg-bad-json": "Błąd w JSON", + "warning-msg-validation": "Ostrzeżenie", + "not-admin-note": "Nie możesz zapisywać na dysku, wymagane uprawnienia administratora" + }, + "app-rebuild": { + "title": "Przebuduj aplikację", + "rebuild-note-l1": "Przebudowanie jest koniecznne po dokonaniu zmian w pliku: conf.yml.", + "rebuild-note-l2": "Powinno to nastąpić automatycznie, jeśli jednak tak się nie stanie możesz je wymusić tutaj.", + "rebuild-note-l3": "Zmiany w pamięci podręcznej nie wymagają przebudowania aplikacji.", + "rebuild-button": "Rozpocznij", + "rebuilding-status-1": "Budowanie...", + "rebuilding-status-2": "Może to zająć kilka minut", + "error-permission": "Nie masz odpowiednich uprawnień do wykonania tej akcji", + "success-msg": "Budowanie zakończone pomyślnie", + "fail-msg": "Budowanie nie powiodło się", + "reload-note": "Zmiany będą widoczne po odświeżeniu strony", + "reload-button": "Odśwież stronę" + }, + "cloud-sync": { + "title": "Kopia zapasowa w chmurze", + "intro-l1": "Tworzenie i przywracanie z chmury to opcjonalna funkcja, która umożliwia zapisanie konfiguracji w sieci, by później wgrać je na innym urządzeniu z Dashy.", + "intro-l2": "Wszystkie dane są w pełni zaszyfrowane z wykorzystaniem AES, kluczem będzie podane hasło.", + "intro-l3": "Aby uzyskać więcej informacji przejdź do", + "backup-title-setup": "Tworzenie", + "backup-title-update": "Zaktualizuj", + "password-label-setup": "Wybierz hasło", + "password-label-update": "Wprowadź hasło", + "backup-button-setup": "Zapisz", + "backup-button-update": "Zaktualizuj", + "backup-id-label": "Identyfikator kopii zapasowej", + "backup-id-note": "Wymagany do przywrócenia. Zapisz wraz z hasłem w bezpiecznym miejscu", + "restore-title": "Przywracanie", + "restore-id-label": "Identyfikator", + "restore-password-label": "Hasło", + "restore-button": "Przywróć", + "backup-missing-password": "Nie podano hasła", + "backup-error-unknown": "Nie udało się wykonać operacji", + "backup-error-password": "Hasło niepoprawne. Proszę wprowadzić aktualne hasło.", + "backup-success-msg": "zakończono pomyślnie", + "restore-success-msg": "Przywrócono pomyślnie" + }, + "menu": { + "sametab": "Otwórz w tej karcie", + "newtab": "Otwórz w nowej karcie", + "modal": "Otwórz w oknie modalnym", + "workspace": "Otwórz w obszarze roboczym" + } +} \ No newline at end of file diff --git a/src/components/Configuration/JsonEditor.vue b/src/components/Configuration/JsonEditor.vue index 09709714..ef90c53d 100644 --- a/src/components/Configuration/JsonEditor.vue +++ b/src/components/Configuration/JsonEditor.vue @@ -156,7 +156,7 @@ export default { localStorage.setItem(localStorageKeys.PAGE_INFO, JSON.stringify(data.pageInfo)); } if (data.appConfig) { - data.appConfig.auth = this.config.appConfig.auth || []; + data.appConfig.auth = this.config.appConfig.auth || {}; localStorage.setItem(localStorageKeys.APP_CONFIG, JSON.stringify(data.appConfig)); } if (data.appConfig.theme) { diff --git a/src/components/LinkItems/Item.vue b/src/components/LinkItems/Item.vue index dcc9ce49..6a602396 100644 --- a/src/components/LinkItems/Item.vue +++ b/src/components/LinkItems/Item.vue @@ -3,8 +3,8 @@ ['newtab', 'sametab', 'modal', 'workspace'].indexOf(value) !== -1, + validator: targetValidator, }, itemSize: String, enableStatusCheck: Boolean, @@ -84,6 +89,25 @@ export default { appConfig() { return this.$store.getters.appConfig; }, + accumulatedTarget() { + return this.target || this.appConfig.defaultOpeningMethod || defaultOpeningMethod; + }, + /* Convert config target value, into HTML anchor target attribute */ + anchorTarget() { + const target = this.accumulatedTarget; + switch (target) { + case 'sametab': return '_self'; + case 'newtab': return '_blank'; + case 'parent': return '_parent'; + case 'top': return '_top'; + default: return undefined; + } + }, + /* Get the href value for the anchor, if not opening in modal/ workspace */ + hyperLinkHref() { + const noAnchorNeeded = ['modal', 'workspace']; + return noAnchorNeeded.includes(this.accumulatedTarget) ? '#' : this.url; + }, }, data() { return { @@ -111,10 +135,10 @@ export default { methods: { /* Called when an item is clicked, manages the opening of modal & resets the search field */ itemOpened(e) { - if (e.altKey || this.target === 'modal') { + if (e.altKey || this.accumulatedTarget === 'modal') { e.preventDefault(); this.$emit('triggerModal', this.url); - } else if (this.target === 'workspace') { + } else if (this.accumulatedTarget === 'workspace') { router.push({ name: 'workspace', query: { url: this.url } }); } else { this.$emit('itemClicked'); @@ -157,12 +181,15 @@ export default { classes: `item-description-tooltip tooltip-is-${this.itemSize}`, }; }, - /* Used by certain themes, which display an icon with animated CSS */ + /* Used by certain themes (material), to show animated CSS icon */ getUnicodeOpeningIcon() { - switch (this.target) { + switch (this.accumulatedTarget) { case 'newtab': return '"\\f360"'; case 'sametab': return '"\\f24d"'; + case 'parent': return '"\\f3bf"'; + case 'top': return '"\\f102"'; case 'modal': return '"\\f2d0"'; + case 'workspace': return '"\\f0b1"'; default: return '"\\f054"'; } }, @@ -304,7 +331,6 @@ export default { /* Text in tile */ .tile-title { white-space: nowrap; - // overflow: hidden; text-overflow: ellipsis; min-width: 120px; height: 30px; diff --git a/src/components/LinkItems/ItemOpenMethodIcon.vue b/src/components/LinkItems/ItemOpenMethodIcon.vue index 17ce4782..b33aa382 100644 --- a/src/components/LinkItems/ItemOpenMethodIcon.vue +++ b/src/components/LinkItems/ItemOpenMethodIcon.vue @@ -5,6 +5,9 @@ + + +

{{ hotkey }} @@ -20,11 +23,14 @@ import NewTabOpenIcon from '@/assets/interface-icons/open-new-tab.svg'; import SameTabOpenIcon from '@/assets/interface-icons/open-current-tab.svg'; import IframeOpenIcon from '@/assets/interface-icons/open-iframe.svg'; import WorkspaceOpenIcon from '@/assets/interface-icons/open-workspace.svg'; +import ParentOpenIcon from '@/assets/interface-icons/open-parent.svg'; +import TopOpenIcon from '@/assets/interface-icons/open-top.svg'; +import UnknownIcon from '@/assets/interface-icons/unknown-icon.svg'; export default { name: 'ItemOpenMethodIcon', props: { - openingMethod: String, // newtab | sametab | modal | workspace + openingMethod: String, // newtab | sametab | parent | top | modal | workspace isSmall: Boolean, // If true, will apply small class position: String, // Position classes: top, bottom, left, right isTransparent: Boolean, // If true, will apply opacity @@ -44,6 +50,9 @@ export default { SameTabOpenIcon, IframeOpenIcon, WorkspaceOpenIcon, + ParentOpenIcon, + TopOpenIcon, + UnknownIcon, }, }; diff --git a/src/styles/color-themes.scss b/src/styles/color-themes.scss index 0f5cbb52..f8ebb1f1 100644 --- a/src/styles/color-themes.scss +++ b/src/styles/color-themes.scss @@ -412,20 +412,11 @@ html[data-theme='material'], html[data-theme='material-dark'] { min-height: 2rem; } } - &.size-large { - width: 18rem; - min-width: 18rem; - max-height: 5rem; - margin: 0.4rem; - img { - padding: 0.2rem 0.5rem; - } - } } .tooltip.item-description-tooltip:not(.tooltip-is-small) { display: none !important; } - .orientation-horizontal { + .orientation-horizontal:not(.single-section-view) { display: flex; flex-direction: column; .there-are-items { @@ -438,6 +429,11 @@ html[data-theme='material'], html[data-theme='material-dark'] { @include big-screen { grid-template-columns: repeat(5, 1fr); } @include big-screen-up { grid-template-columns: repeat(6, 1fr); } } + .there-are-items .item-wrapper .item { + width: auto; + min-width: auto; + max-height: auto; + } } a.item { position: relative; @@ -486,15 +482,9 @@ html[data-theme='material'], html[data-theme='material-dark'] { padding-left: 0.5rem; min-width: 11rem; } - &.size-large { - &:before { - width: 1.5rem; - } - &:hover { - div:nth-child(2) { - text-indent: 1.5rem; - } - } + &.short:not(.size-large) { + min-height: 2rem; + height: auto; } } } diff --git a/src/utils/ConfigHelpers.js b/src/utils/ConfigHelpers.js index d8ce987f..974f9935 100644 --- a/src/utils/ConfigHelpers.js +++ b/src/utils/ConfigHelpers.js @@ -7,6 +7,8 @@ import { theme as defaultTheme, language as defaultLanguage, } from '@/utils/defaults'; +import ErrorHandler from '@/utils/ErrorHandler'; +import ConfigSchema from '@/utils/ConfigSchema.json'; /** * Initiates the Accumulator class and generates a complete config object @@ -97,3 +99,17 @@ export const getUsersLanguage = () => { const langObj = languages.find(lang => lang.code === langCode); return langObj; }; + +/** + * validator for item target attribute + * Uses enum values from config schema, and shows warning if invalid + * @param {String} target + * @returns {Boolean} isValid + */ +export const targetValidator = (target) => { + const acceptedTargets = ConfigSchema.properties.sections.items + .properties.items.items.properties.target.enum; + const isTargetValid = acceptedTargets.indexOf(target) !== -1; + if (!isTargetValid) ErrorHandler(`Unknown target value: ${target}`); + return isTargetValid; +}; diff --git a/src/utils/ConfigSchema.json b/src/utils/ConfigSchema.json index 707dc060..d842575f 100644 --- a/src/utils/ConfigSchema.json +++ b/src/utils/ConfigSchema.json @@ -75,6 +75,20 @@ "default": "default", "description": "Which page to load by default, and on the base page or domain root. You can still switch to different views from within the UI" }, + "defaultOpeningMethod": { + "title": "Default Opening Method", + "type": "string", + "enum": [ + "newtab", + "sametab", + "parent", + "top", + "modal", + "workspace" + ], + "default": "newtab", + "description": "The default opening method for items. Only used if no item.target is specified" + }, "statusCheck": { "title": "Enable Status Checks", "type": "boolean", @@ -616,6 +630,8 @@ "enum": [ "newtab", "sametab", + "parent", + "top", "modal", "workspace" ], diff --git a/src/utils/defaults.js b/src/utils/defaults.js index bfab3010..80c314bd 100644 --- a/src/utils/defaults.js +++ b/src/utils/defaults.js @@ -142,6 +142,8 @@ module.exports = { metaTagData: [ { name: 'description', content: 'A simple static homepage for you\'re server' }, ], + /* If no 'target' specified, this is the default opening method */ + openingMethod: 'newtab', /* Default option for Toast messages */ toastedOptions: { position: 'bottom-center', diff --git a/src/utils/languages.js b/src/utils/languages.js index 9b7b8d32..bea5b973 100644 --- a/src/utils/languages.js +++ b/src/utils/languages.js @@ -2,6 +2,7 @@ import en from '@/assets/locales/en.json'; import de from '@/assets/locales/de.json'; import nl from '@/assets/locales/nl.json'; +import pl from '@/assets/locales/pl.json'; import fr from '@/assets/locales/fr.json'; import sl from '@/assets/locales/sl.json'; import es from '@/assets/locales/es.json'; @@ -12,6 +13,7 @@ import hi from '@/assets/locales/hi.json'; import ja from '@/assets/locales/ja.json'; import pt from '@/assets/locales/pt.json'; import ru from '@/assets/locales/ru.json'; +import nb from '@/assets/locales/nb.json'; import pirate from '@/assets/locales/zz-pirate.json'; // Language data - Next register your language by adding it to this list @@ -34,6 +36,12 @@ export const languages = [ locale: nl, flag: '🇳🇱', }, + { + name: 'polski', + code: 'pl', + locale: pl, + flag: '🇵🇱', + }, { name: 'Français', code: 'fr', @@ -94,6 +102,12 @@ export const languages = [ locale: ru, flag: '🇷🇺', }, + { // Norwegian + name: 'Norsk', + code: 'nb', + locale: nb, + flag: '🇳🇴', + }, { // Joke Language - Pirate name: 'Pirate', code: 'pirate', diff --git a/yarn.lock b/yarn.lock index 95e9b04c..bcc9a754 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2198,12 +2198,12 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -axios@^0.21.4: - version "0.21.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" - integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== +axios@^0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.22.0.tgz#bf702c41fb50fbca4539589d839a077117b79b25" + integrity sha512-Z0U3uhqQeg1oNcihswf4ZD57O3NrR1+ZXhxaROaWpDmsDTx7T2HNBV2ulBtie2hwJptu8UvgnJoK+BIqdzh/1w== dependencies: - follow-redirects "^1.14.0" + follow-redirects "^1.14.4" babel-eslint@^10.0.1: version "10.1.0" @@ -4657,7 +4657,7 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" -follow-redirects@^1.0.0, follow-redirects@^1.14.0: +follow-redirects@^1.0.0, follow-redirects@^1.14.4: version "1.14.4" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379" integrity sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==