Merge branch 'master' of github.com:Lissy93/dashy into FEATURE/minimal-view
This commit is contained in:
@@ -147,5 +147,11 @@
|
||||
"backup-error-password": "Incorrect password. Please enter your current password.",
|
||||
"backup-success-msg": "Completed Successfully",
|
||||
"restore-success-msg": "Config Restored Successfully"
|
||||
},
|
||||
"menu": {
|
||||
"sametab": "Open in Current Tab",
|
||||
"newtab": "Open in New Tab",
|
||||
"modal": "Open in Pop-Up Modal",
|
||||
"workspace": "Open in Workspace View"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,5 +147,11 @@
|
||||
"backup-error-password": "Mot de passe incorrect. Veuillez saisir votre mot de passe actuel.",
|
||||
"backup-success-msg": "Sauvegarde effectuée avec succès",
|
||||
"restore-success-msg": "Configuration restaurée avec succès"
|
||||
},
|
||||
"menu": {
|
||||
"sametab": "Ouvrir dans l'onglet actuel",
|
||||
"newtab": "Ouvrir dans un nouvel onglet",
|
||||
"modal": "Ouvrir en mode fenêtré",
|
||||
"workspace": "Ouvrir en mode plein écran"
|
||||
}
|
||||
}
|
||||
|
||||
157
src/assets/locales/sl.json
Normal file
157
src/assets/locales/sl.json
Normal file
@@ -0,0 +1,157 @@
|
||||
{
|
||||
"home": {
|
||||
"no-results": "Ni Rezultatov Iskanja",
|
||||
"no-data": "Podatki Niso Konfigurirani"
|
||||
},
|
||||
"search": {
|
||||
"search-label": "Iskanje",
|
||||
"search-placeholder": "Začnite tipkati za filtrirate",
|
||||
"clear-search-tooltip": "Počisti iskanje"
|
||||
},
|
||||
"login": {
|
||||
"title": "Dashy",
|
||||
"username-label": "Uporabniško ime",
|
||||
"password-label": "Geslo",
|
||||
"login-button": "Prijava",
|
||||
"remember-me-label": "Zapomni si me za",
|
||||
"remember-me-never": "Nikoli",
|
||||
"remember-me-hour": "4 Ure",
|
||||
"remember-me-day": "1 Dan",
|
||||
"remember-me-week": "1 Teden",
|
||||
"error-missing-username": "Manjka Uporabniško Ime",
|
||||
"error-missing-password": "Manjka Geslo",
|
||||
"error-incorrect-username": "Uporabnik ne obstaja",
|
||||
"error-incorrect-password": "Napačno Geslo",
|
||||
"success-message": "Prijavljanje...",
|
||||
"logout-message": "Odjavljen"
|
||||
},
|
||||
"config": {
|
||||
"main-tab": "Glavni Meni",
|
||||
"view-config-tab": "Ogled Konfiguracije",
|
||||
"edit-config-tab": "Urejanje Konfiguracije",
|
||||
"custom-css-tab": "Slogi Po Meri",
|
||||
"heading": "Možnosti Konfiguracija",
|
||||
"download-config-button": "Prenos Konfiguracije",
|
||||
"edit-config-button": "Uredi Konfiguracijo",
|
||||
"edit-css-button": "Uredi CSS Po Meri",
|
||||
"cloud-sync-button": "Omogoči Sinhronizacijo v Oblaku",
|
||||
"edit-cloud-sync-button": "Ureditev Sinhronizacije v Oblaku",
|
||||
"rebuild-app-button": "Obnovi Aplikacijo",
|
||||
"change-language-button": "Spremeni Jezik Aplikacije",
|
||||
"reset-settings-button": "Ponastavi Lokalne Nastavitve",
|
||||
"app-info-button": "Informacije o Aplikaciji",
|
||||
"backup-note": "Priporočljivo je, da pred spremembami naredite varnostno kopijo konfiguracije.",
|
||||
"reset-config-msg-l1": "To bo odstranilo vse uporabniške nastavitve iz lokalnega pomnilnika, vendar ne bo vplivalo na datoteko 'conf.yml'.",
|
||||
"reset-config-msg-l2": "Če želeti spremembe, ki ste jih naredili lokalno uporabiti v prihodnosti, ustvarite varnostno kopijo.",
|
||||
"reset-config-msg-l3": "Ali ste prepričani, da želite nadaljevati?",
|
||||
"data-cleared-msg": "Podatki so bili uspešno izbrisani",
|
||||
"actions-label": "Dejanja",
|
||||
"copy-config-label": "Kopiraj Konfiguracijo",
|
||||
"data-copied-msg": "Config je bil kopiran v odložišče",
|
||||
"reset-config-label": "Ponastavi Konfiguracijo",
|
||||
"css-save-btn": "Shrani spremembe",
|
||||
"css-note-label": "Opomba",
|
||||
"css-note-l1": "Za uveljavitev sprememb boste morali osvežiti stran.",
|
||||
"css-note-l2": "Preglasitve slogov so shranjene samo lokalno, zato je priporočljivo narediti kopijo CSS -ja.",
|
||||
"css-note-l3": "Če želite odstraniti vse sloge po meri, izbrišite vsebino in pritisnite Shrani spremembe"
|
||||
},
|
||||
"settings": {
|
||||
"theme-label": "Tema",
|
||||
"layout-label": "Postavitev",
|
||||
"layout-auto": "Avtomatsko",
|
||||
"layout-horizontal": "Vodoravno",
|
||||
"layout-vertical": "Vertikalno",
|
||||
"item-size-label": "Velikost Predmeta",
|
||||
"item-size-small": "Majhno",
|
||||
"item-size-medium": "Srednje",
|
||||
"item-size-large": "Veliko",
|
||||
"config-launcher-label": "Nastavitve",
|
||||
"config-launcher-tooltip": "Posodobi Konfiguracijo",
|
||||
"sign-out-tooltip": "Odjava"
|
||||
},
|
||||
"updates": {
|
||||
"app-version-note": "Dashy verzija",
|
||||
"up-to-date": "Posodobljeno",
|
||||
"out-of-date": "Navoljo posodobitev",
|
||||
"unsupported-version-l1": "Uporabljate nepodprto različico programa Dashy",
|
||||
"unsupported-version-l2": "Za najboljšo izkušnjo in najnovejše varnostne popravke posodobite na"
|
||||
},
|
||||
"language-switcher": {
|
||||
"title": "Spremenite Jezik Aplikacije",
|
||||
"dropdown-label": "Izberite Jezik",
|
||||
"save-button": "Shrani",
|
||||
"success-msg": "Jezik Posodobljen na"
|
||||
},
|
||||
"theme-maker": {
|
||||
"title": "Konfigurator Teme",
|
||||
"export-button": "Izvozi Spremenljivke po Meri",
|
||||
"reset-button": "Ponastavi Sloge za",
|
||||
"show-all-button": "Pokaži Vse Spremenljivke",
|
||||
"save-button": "Shrani",
|
||||
"cancel-button": "Prekliči",
|
||||
"saved-toast": "{theme} Posodbljena Uspešno",
|
||||
"copied-toast": "Podatki o temi za {theme} so kopirani v odložišče",
|
||||
"reset-toast": "Barve po Meri za {theme} Odstranjene"
|
||||
},
|
||||
"config-editor": {
|
||||
"save-location-label": "Način Shranjevanja",
|
||||
"location-local-label": "Shrani Lokalno",
|
||||
"location-disk-label": "Zapišite spremembe v datoteko za konfiguracijo",
|
||||
"save-button": "Shrani Spremembe",
|
||||
"valid-label": "Konfiguracija je veljavna",
|
||||
"status-success-msg": "Operacija dokončana",
|
||||
"status-fail-msg": "Operacija ni uspela",
|
||||
"success-msg-disk": "Konfiguracijska datoteka je uspešno zapisana na disk",
|
||||
"success-msg-local": "Lokalne spremembe so bile uspešno shranjene",
|
||||
"success-note-l1": "Aplikacija se bo samodejno obnovila.",
|
||||
"success-note-l2": "To lahko traja do ene minute.",
|
||||
"success-note-l3": "Za uveljavitev sprememb boste morali osvežiti stran.",
|
||||
"error-msg-save-mode": "Izberite način shranjevanja: Lokalno ali v Datoteko",
|
||||
"error-msg-cannot-save": "Pri shranjevanju konfiguracije je prišlo do napake",
|
||||
"error-msg-bad-json": "Napaka v JSON -u, morda nepravilno oblikovana",
|
||||
"warning-msg-validation": "Opozorilo o Validaciji"
|
||||
},
|
||||
"app-rebuild": {
|
||||
"title": "Obnovite Aplikacijo",
|
||||
"rebuild-note-l1": "Za uveljavitev sprememb, zapisanih v datoteki conf.yml, je potrebna obnovitev.",
|
||||
"rebuild-note-l2": "To bi se moralo zgoditi samodejno, če pa se ne, lahko to ročno sprožite tukaj.",
|
||||
"rebuild-note-l3": "To ni potrebno za spremembe, shranjene lokalno.",
|
||||
"rebuild-button": "Začni Graditi",
|
||||
"rebuilding-status-1": "Gradnja...",
|
||||
"rebuilding-status-2": "To lahko traja nekaj minut",
|
||||
"error-permission": "Nimate dovoljenja za izvajanje tega dejanja",
|
||||
"success-msg": "Gradnja je bila uspešno zaključena",
|
||||
"fail-msg": "Operacija izdelave ni uspela",
|
||||
"reload-note": "Za uveljavitev sprememb je potrebno osvežiti stran",
|
||||
"reload-button": "Osveži Stran"
|
||||
},
|
||||
"cloud-sync": {
|
||||
"title": "Varnostno Kopiranje & Obnovitev v Oblaku",
|
||||
"intro-l1": "Varnostno kopiranje in obnovitev v oblaku je izbirna funkcija, ki vam omogoča, da svojo konfiguracijo shranite v oblak in jo nato obnovite v kateri koli drugi napravi ali primerku Dashyja.",
|
||||
"intro-l2": "Vsi podatki so v celoti šifrirani z AES, pri čemer je vaše geslo ključ.",
|
||||
"intro-l3": "Za več informacij si oglejte",
|
||||
"backup-title-setup": "Ustvari Varnostno Kopijo",
|
||||
"backup-title-update": "Posodobi Varnostno Kopijo",
|
||||
"password-label-setup": "Izberi Geslo",
|
||||
"password-label-update": "Vnesite Geslo",
|
||||
"backup-button-setup": "Varnosto Kopiraj",
|
||||
"backup-button-update": "Posodobi Varnostno Kopijo",
|
||||
"backup-id-label": "Vaš Obnovitveni ID",
|
||||
"backup-id-note": "To se uporabi za obnovitev iz varnostnih kopij pozneje. Zato ga skupaj z geslom hranite na varnem.",
|
||||
"restore-title": "Obnovite Varnostno Kopijo",
|
||||
"restore-id-label": "Obnovitveni ID",
|
||||
"restore-password-label": "Geslo",
|
||||
"restore-button": "Obnovi",
|
||||
"backup-missing-password": "Vnesite geslo",
|
||||
"backup-error-unknown": "Zahteve ni mogoče obdelati",
|
||||
"backup-error-password": "Napačno geslo. Prosim vnesite vaše trenutno geslo.",
|
||||
"backup-success-msg": "Uspešno Zaključeno",
|
||||
"restore-success-msg": "Konfiguracija Uspešno Obnovljena"
|
||||
},
|
||||
"menu": {
|
||||
"sametab": "Odpri v Trenutnem Zavihku",
|
||||
"newtab": "Odpri v Novem Zavihku",
|
||||
"modal": "Odpri v Pojavnem Oknu",
|
||||
"workspace": "Odpri v Delovnem Pogledu"
|
||||
}
|
||||
}
|
||||
@@ -5,19 +5,19 @@
|
||||
<ul>
|
||||
<li @click="launch('sametab')">
|
||||
<SameTabOpenIcon />
|
||||
<span>Open in Current Tab</span>
|
||||
<span>{{ $t('menu.sametab') }}</span>
|
||||
</li>
|
||||
<li @click="launch('newtab')">
|
||||
<NewTabOpenIcon />
|
||||
<span>Open in New Tab</span>
|
||||
<span>{{ $t('menu.newtab') }}</span>
|
||||
</li>
|
||||
<li @click="launch('modal')">
|
||||
<IframeOpenIcon />
|
||||
<span>Open in Pop-Up Modal</span>
|
||||
<span>{{ $t('menu.modal') }}</span>
|
||||
</li>
|
||||
<li @click="launch('workspace')">
|
||||
<WorkspaceOpenIcon />
|
||||
<span>Open in Workspace View</span>
|
||||
<span>{{ $t('menu.workspace') }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<a @click="itemOpened"
|
||||
@mouseup.right="openContextMenu"
|
||||
@contextmenu.prevent
|
||||
:href="target !== 'modal' ? url : '#'"
|
||||
:href="(target !== 'modal' && target !== 'workspace') ? url : '#'"
|
||||
:target="target === 'newtab' ? '_blank' : ''"
|
||||
:class="`item ${!icon? 'short': ''} size-${itemSize}`"
|
||||
v-tooltip="getTooltipOptions()"
|
||||
@@ -100,6 +100,8 @@ export default {
|
||||
if (e.altKey || this.target === 'modal') {
|
||||
e.preventDefault();
|
||||
this.$emit('triggerModal', this.url);
|
||||
} else if (this.target === 'workspace') {
|
||||
router.push({ name: 'workspace', query: { url: this.url } });
|
||||
} else {
|
||||
this.$emit('itemClicked');
|
||||
}
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
<template>
|
||||
<div class="item-icon">
|
||||
<!-- Font-Awesome Icon -->
|
||||
<i v-if="iconType === 'font-awesome'" :class="`${icon} ${size}`" ></i>
|
||||
<!-- Emoji Icon -->
|
||||
<i v-else-if="iconType === 'emoji'" :class="`emoji-icon ${size}`" >{{getEmoji(iconPath)}}</i>
|
||||
<!-- Material Design Icon -->
|
||||
<span v-else-if="iconType === 'mdi'" :class=" `mdi ${icon} ${size}`"></span>
|
||||
<!-- Simple-Icons -->
|
||||
<object v-else-if="iconType === 'si'" :class="`simple-icons ${size}`"
|
||||
type="image/svg+xml" :data="getSimpleIcon(icon)"></object>
|
||||
<!-- Standard image asset icon -->
|
||||
<img v-else-if="icon" :src="iconPath" @error="imageNotFound"
|
||||
:class="`tile-icon ${size} ${broken ? 'broken' : ''}`"
|
||||
/>
|
||||
<!-- Icon could not load/ broken url -->
|
||||
<BrokenImage v-if="broken" class="missing-image" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -12,7 +21,7 @@
|
||||
<script>
|
||||
import BrokenImage from '@/assets/interface-icons/broken-icon.svg';
|
||||
import ErrorHandler from '@/utils/ErrorHandler';
|
||||
import { faviconApi as defaultFaviconApi, faviconApiEndpoints } from '@/utils/defaults';
|
||||
import { faviconApi as defaultFaviconApi, faviconApiEndpoints, iconCdns } from '@/utils/defaults';
|
||||
import EmojiUnicodeRegex from '@/utils/EmojiUnicodeRegex';
|
||||
import emojiLookup from '@/utils/emojis.json';
|
||||
|
||||
@@ -28,17 +37,18 @@ export default {
|
||||
BrokenImage,
|
||||
},
|
||||
computed: {
|
||||
/* Determines the type of icon */
|
||||
iconType: function iconType() {
|
||||
return this.determineImageType(this.icon);
|
||||
},
|
||||
/* Gets the icon path, dependent on icon type */
|
||||
iconPath: function iconPath() {
|
||||
return this.getIconPath(this.icon, this.url);
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
broken: false,
|
||||
// faviconApi: this.config.appConfig.faviconApi || defaultFaviconApi,
|
||||
broken: false, // If true, was unable to resolve icon
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -80,7 +90,7 @@ export default {
|
||||
getFavicon(fullUrl) {
|
||||
if (this.shouldUseDefaultFavicon(fullUrl)) { // Check if we should use local icon
|
||||
const urlParts = fullUrl.split('/');
|
||||
if (urlParts.length >= 2) return `${urlParts[0]}/${urlParts[1]}/${urlParts[2]}/favicon.ico`;
|
||||
if (urlParts.length >= 2) return `${urlParts[0]}/${urlParts[1]}/${urlParts[2]}/${iconCdns.faviconName}`;
|
||||
} else if (fullUrl.includes('http')) { // Service is running publicly
|
||||
const host = this.getHostName(fullUrl);
|
||||
const faviconApi = this.config.appConfig.faviconApi || defaultFaviconApi;
|
||||
@@ -95,11 +105,18 @@ export default {
|
||||
const isLocalIP = /(127\.)|(192\.168\.)|(10\.)|(172\.1[6-9]\.)|(172\.2[0-9]\.)|(172\.3[0-1]\.)|(::1$)|([fF][cCdD])|(localhost)/;
|
||||
return (isLocalIP.test(fullUrl) || this.config.appConfig.faviconApi === 'local');
|
||||
},
|
||||
/* Fetches the path of local images, from Docker container */
|
||||
getLocalImagePath(img) {
|
||||
return `/item-icons/${img}`;
|
||||
return `${iconCdns.localPath}/${img}`;
|
||||
},
|
||||
/* Formats the URL for fetching the generative icons */
|
||||
getGenerativeIcon(url) {
|
||||
return `https://ipsicon.io/${this.getHostName(url)}.svg`;
|
||||
return `${iconCdns.generative}/${this.getHostName(url)}.svg`;
|
||||
},
|
||||
/* Formats the URL for getting Simple-Icons SVG asset */
|
||||
getSimpleIcon(img) {
|
||||
const imageName = img.replace('si-', '');
|
||||
return `${iconCdns.si}/${imageName}.svg`;
|
||||
},
|
||||
/* Checks if the icon is from a local image, remote URL, SVG or font-awesome */
|
||||
getIconPath(img, url) {
|
||||
@@ -108,8 +125,10 @@ export default {
|
||||
case 'img': return this.getLocalImagePath(img);
|
||||
case 'favicon': return this.getFavicon(url);
|
||||
case 'generative': return this.getGenerativeIcon(url);
|
||||
case 'svg': return img;
|
||||
case 'emoji': return img;
|
||||
case 'mdi': return img; // Material design icons
|
||||
case 'simple-icons': return this.getSimpleIcon(img);
|
||||
case 'svg': return img; // Local SVG icon
|
||||
case 'emoji': return img; // Emoji/ unicode
|
||||
default: return '';
|
||||
}
|
||||
},
|
||||
@@ -121,12 +140,15 @@ export default {
|
||||
else if (this.isUrl(img)) imgType = 'url';
|
||||
else if (this.isImage(img)) imgType = 'img';
|
||||
else if (img.includes('fa-')) imgType = 'font-awesome';
|
||||
else if (img.includes('mdi-')) imgType = 'mdi';
|
||||
else if (img.includes('si-')) imgType = 'si';
|
||||
else if (img === 'favicon') imgType = 'favicon';
|
||||
else if (img === 'generative') imgType = 'generative';
|
||||
else if (this.isEmoji(img).isEmoji) imgType = 'emoji';
|
||||
else imgType = 'none';
|
||||
return imgType;
|
||||
},
|
||||
/* For a given URL, return the hostname only. Used for favicon and generative icons */
|
||||
getHostName(url) {
|
||||
try { return new URL(url).hostname; } catch (e) { return url; }
|
||||
},
|
||||
@@ -140,6 +162,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* Default Image Icon */
|
||||
.tile-icon {
|
||||
width: 2rem;
|
||||
// filter: var(--item-icon-transform);
|
||||
@@ -152,7 +175,8 @@ export default {
|
||||
width: 3rem;
|
||||
}
|
||||
}
|
||||
i.fas, i.fab, i.far, i.fal, i.fad {
|
||||
/* Font-Awesome and Material Design Icons */
|
||||
i.fas, i.fab, i.far, i.fal, i.fad, span.mdi {
|
||||
font-size: 2rem;
|
||||
color: currentColor;
|
||||
margin: 1px 4px;
|
||||
@@ -163,6 +187,9 @@ export default {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
span.mdi {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
object.tile-icon {
|
||||
width: 55px;
|
||||
height: 55px;
|
||||
@@ -170,6 +197,13 @@ export default {
|
||||
fill: currentColor;
|
||||
}
|
||||
}
|
||||
/* Simple Icons */
|
||||
object.simple-icons {
|
||||
width: 2rem;
|
||||
&.small { width: 1.5rem; }
|
||||
&.large { width: 2.5rem; }
|
||||
}
|
||||
/* Emoji Icons */
|
||||
i.emoji-icon {
|
||||
font-style: normal;
|
||||
font-size: 2rem;
|
||||
@@ -181,6 +215,7 @@ export default {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
/* Icon Not Found */
|
||||
.missing-image {
|
||||
width: 3.5rem;
|
||||
path {
|
||||
|
||||
62
src/components/Workspace/MultiTaskingWebComtent.vue
Normal file
62
src/components/Workspace/MultiTaskingWebComtent.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="multi-taking-view" ref="container"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue';
|
||||
import WebContent from '@/components/Workspace/WebContent';
|
||||
|
||||
export default {
|
||||
name: 'WebContent',
|
||||
props: {
|
||||
url: String, // The URL of currently visible app
|
||||
},
|
||||
data: () => ({
|
||||
openApps: [], // List of all currently open apps
|
||||
}),
|
||||
watch: {
|
||||
/* Update the currently open app, when URL changes */
|
||||
url() { this.launchApp(); },
|
||||
},
|
||||
methods: {
|
||||
/* Check if app already open or not, and call appropriate opener */
|
||||
launchApp() {
|
||||
if (this.openApps.includes(this.url)) {
|
||||
this.openExistingApp();
|
||||
} else {
|
||||
this.openApps.push(this.url);
|
||||
this.appendNewApp();
|
||||
}
|
||||
},
|
||||
/* Opens a new app */
|
||||
appendNewApp() {
|
||||
const ComponentClass = Vue.extend(WebContent);
|
||||
const instance = new ComponentClass({
|
||||
propsData: { url: this.url, id: btoa(this.url) },
|
||||
});
|
||||
instance.$mount(); // pass nothing
|
||||
this.$refs.container.appendChild(instance.$el);
|
||||
},
|
||||
/* Switches visibility to an already open app */
|
||||
openExistingApp() {
|
||||
Array.from(document.getElementsByClassName('web-content')).forEach((frame) => {
|
||||
frame.classList.add('hide');
|
||||
});
|
||||
document.getElementById(btoa(this.url)).classList.remove('hide');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
iframe {
|
||||
position: absolute;
|
||||
left: var(--side-bar-width);
|
||||
height: calc(100% - var(--header-height));
|
||||
width: calc(100% - var(--side-bar-width));
|
||||
border: none;
|
||||
background: white;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -44,8 +44,6 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/styles/media-queries.scss';
|
||||
@import '@/styles/style-helpers.scss';
|
||||
|
||||
div.side-bar-item {
|
||||
color: var(--side-bar-color);
|
||||
@@ -56,8 +54,10 @@ div.side-bar-item {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
p.small-title {
|
||||
margin: 0.1rem auto;
|
||||
margin: 0.1rem 0 0 -0.5rem;
|
||||
font-size: 0.6rem;
|
||||
transform: rotate(-25deg);
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="web-content">
|
||||
<div class="web-content" :id="id">
|
||||
<iframe :src="url" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -10,13 +10,15 @@ export default {
|
||||
name: 'WebContent',
|
||||
props: {
|
||||
url: String,
|
||||
id: {
|
||||
type: String,
|
||||
default: 'web-app-view',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/styles/media-queries.scss';
|
||||
@import '@/styles/style-helpers.scss';
|
||||
|
||||
iframe {
|
||||
position: absolute;
|
||||
@@ -27,4 +29,8 @@ iframe {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.web-content.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -239,6 +239,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"enableMultiTasking": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "If set to true, will keep apps opened in the workspace open in the background. Useful for switching between sites, but comes at the cost of performance"
|
||||
},
|
||||
"allowConfigEdit": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
|
||||
@@ -131,6 +131,15 @@ module.exports = {
|
||||
allesedv: 'https://f1.allesedv.com/128/$URL',
|
||||
webmasterapi: 'https://api.webmasterapi.com/v1/favicon/yEwx0ZFs0CSPshHq/$URL',
|
||||
},
|
||||
/* The URL to CDNs used for external icons. These are only loaded when required */
|
||||
iconCdns: {
|
||||
fa: 'https://kit.fontawesome.com',
|
||||
mdi: 'https://cdn.jsdelivr.net/npm/@mdi/font@5.9.55/css/materialdesignicons.min.css',
|
||||
si: 'https://unpkg.com/simple-icons@v5/icons',
|
||||
generative: 'https://ipsicon.io',
|
||||
localPath: '/item-icons',
|
||||
faviconName: 'favicon.ico',
|
||||
},
|
||||
/* Available built-in colors for the theme builder */
|
||||
swatches: [
|
||||
['#eb5cad', '#985ceb', '#5346f3', '#5c90eb'],
|
||||
|
||||
@@ -3,6 +3,7 @@ import en from '@/assets/locales/en.json';
|
||||
import de from '@/assets/locales/de.json';
|
||||
import nl from '@/assets/locales/nl.json';
|
||||
import fr from '@/assets/locales/fr.json';
|
||||
import sl from '@/assets/locales/sl.json';
|
||||
|
||||
// Language data - Add your country name, locale code and imported file here
|
||||
export const languages = [
|
||||
@@ -30,6 +31,12 @@ export const languages = [
|
||||
locale: fr,
|
||||
flag: '🇲🇫',
|
||||
},
|
||||
{
|
||||
name: 'Slovenian',
|
||||
code: 'sl',
|
||||
locale: sl,
|
||||
flag: '🇸🇮',
|
||||
},
|
||||
// Including:
|
||||
// name - Human readable name for your language (e.g German)
|
||||
// code - ISO language code (e.g. de)
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
import SettingsContainer from '@/components/Settings/SettingsContainer.vue';
|
||||
import ItemGroup from '@/components/LinkItems/ItemGroup.vue';
|
||||
import Defaults, { localStorageKeys } from '@/utils/defaults';
|
||||
import Defaults, { localStorageKeys, iconCdns } from '@/utils/defaults';
|
||||
|
||||
export default {
|
||||
name: 'home',
|
||||
@@ -160,16 +160,21 @@ export default {
|
||||
availibleThemes.Default = '#';
|
||||
return availibleThemes;
|
||||
},
|
||||
/* Checks if any of the icons are Font Awesome glyphs */
|
||||
checkIfFontAwesomeNeeded() {
|
||||
/* Checks if any sections or items use icons from a given CDN */
|
||||
checkIfIconLibraryNeeded(prefix) {
|
||||
let isNeeded = false;
|
||||
if (!this.sections) return false;
|
||||
this.sections.forEach((section) => {
|
||||
if (section.icon && section.icon.includes('fa-')) isNeeded = true;
|
||||
if (section.icon && section.icon.includes(prefix)) isNeeded = true;
|
||||
section.items.forEach((item) => {
|
||||
if (item.icon && item.icon.includes('fa-')) isNeeded = true;
|
||||
if (item.icon && item.icon.includes(prefix)) isNeeded = true;
|
||||
});
|
||||
});
|
||||
return isNeeded;
|
||||
},
|
||||
/* Checks if any of the icons are Font Awesome glyphs */
|
||||
checkIfFontAwesomeNeeded() {
|
||||
let isNeeded = this.checkIfIconLibraryNeeded('fa-');
|
||||
const currentTheme = localStorage[localStorageKeys.THEME]; // Some themes require FA
|
||||
if (['material', 'material-dark'].includes(currentTheme)) isNeeded = true;
|
||||
return isNeeded;
|
||||
@@ -179,10 +184,23 @@ export default {
|
||||
if (this.appConfig.enableFontAwesome || this.checkIfFontAwesomeNeeded()) {
|
||||
const fontAwesomeScript = document.createElement('script');
|
||||
const faKey = this.appConfig.fontAwesomeKey || Defaults.fontAwesomeKey;
|
||||
fontAwesomeScript.setAttribute('src', `https://kit.fontawesome.com/${faKey}.js`);
|
||||
fontAwesomeScript.setAttribute('src', `${iconCdns.fa}/${faKey}.js`);
|
||||
document.head.appendChild(fontAwesomeScript);
|
||||
}
|
||||
},
|
||||
/* Checks if any of the icons are Material Design Icons */
|
||||
checkIfMdiNeeded() {
|
||||
return this.checkIfIconLibraryNeeded('mdi-');
|
||||
},
|
||||
/* Injects Material Design Icons, only if needed */
|
||||
initiateMaterialDesignIcons() {
|
||||
if (this.checkIfMdiNeeded()) {
|
||||
const mdiStylesheet = document.createElement('link');
|
||||
mdiStylesheet.setAttribute('rel', 'stylesheet');
|
||||
mdiStylesheet.setAttribute('href', iconCdns.mdi);
|
||||
document.head.appendChild(mdiStylesheet);
|
||||
}
|
||||
},
|
||||
/* Returns true if there is more than 1 sub-result visible during searching */
|
||||
checkIfResults() {
|
||||
if (!this.sections) return false;
|
||||
@@ -204,6 +222,7 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.initiateFontAwesome();
|
||||
this.initiateMaterialDesignIcons();
|
||||
this.layout = this.layoutOrientation;
|
||||
this.itemSizeBound = this.iconSize;
|
||||
},
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<div class="work-space">
|
||||
<SideBar :sections="sections" @launch-app="launchApp" />
|
||||
<WebContent :url="url" />
|
||||
<WebContent :url="url" v-if="!isMultiTaskingEnabled" />
|
||||
<MultiTaskingWebComtent :url="url" v-else />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -9,6 +10,7 @@
|
||||
|
||||
import SideBar from '@/components/Workspace/SideBar';
|
||||
import WebContent from '@/components/Workspace/WebContent';
|
||||
import MultiTaskingWebComtent from '@/components/Workspace/MultiTaskingWebComtent';
|
||||
import Defaults from '@/utils/defaults';
|
||||
import { GetTheme, ApplyLocalTheme, ApplyCustomVariables } from '@/utils/ThemeHelper';
|
||||
|
||||
@@ -24,9 +26,15 @@ export default {
|
||||
ApplyLocalTheme,
|
||||
ApplyCustomVariables,
|
||||
}),
|
||||
computed: {
|
||||
isMultiTaskingEnabled() {
|
||||
return this.appConfig.enableMultiTasking || false;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
SideBar,
|
||||
WebContent,
|
||||
MultiTaskingWebComtent,
|
||||
},
|
||||
methods: {
|
||||
launchApp(url) {
|
||||
|
||||
Reference in New Issue
Block a user