mirror of https://github.com/lissy93/dashy
✨ Basic multi-page support working (#584)
This commit is contained in:
parent
cf7587b4ee
commit
036bc008c5
|
@ -1,12 +1,12 @@
|
|||
<template>
|
||||
<div class="nav-outer" v-if="links && links.length > 0">
|
||||
<div class="nav-outer" v-if="allLinks && allLinks.length > 0">
|
||||
<IconBurger
|
||||
:class="`burger ${!navVisible ? 'visible' : ''}`"
|
||||
@click="navVisible = !navVisible"
|
||||
/>
|
||||
<nav id="nav" v-if="navVisible">
|
||||
<!-- Render either router-link or anchor, depending if internal / external link -->
|
||||
<template v-for="(link, index) in links">
|
||||
<template v-for="(link, index) in allLinks">
|
||||
<router-link v-if="!isUrl(link.path)"
|
||||
:key="index"
|
||||
:to="link.path"
|
||||
|
@ -28,6 +28,7 @@
|
|||
|
||||
<script>
|
||||
import IconBurger from '@/assets/interface-icons/burger-menu.svg';
|
||||
import { makePageSlug } from '@/utils/ConfigHelpers';
|
||||
|
||||
export default {
|
||||
name: 'Nav',
|
||||
|
@ -41,6 +42,17 @@ export default {
|
|||
navVisible: true,
|
||||
isMobile: false,
|
||||
}),
|
||||
computed: {
|
||||
/* Get links to sub-pages, and combine with nav-links */
|
||||
allLinks() {
|
||||
const subPages = this.$store.getters.pages.map((subPage) => ({
|
||||
path: makePageSlug(subPage.path, 'home'),
|
||||
title: subPage.name,
|
||||
}));
|
||||
const navLinks = this.links || [];
|
||||
return [...navLinks, ...subPages];
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.navVisible = !this.detectMobile();
|
||||
this.isMobile = this.detectMobile();
|
||||
|
|
|
@ -3,10 +3,13 @@
|
|||
*/
|
||||
|
||||
import Defaults, { localStorageKeys, iconCdns } from '@/utils/defaults';
|
||||
import Keys from '@/utils/StoreMutations';
|
||||
import { searchTiles } from '@/utils/Search';
|
||||
|
||||
const HomeMixin = {
|
||||
props: {},
|
||||
props: {
|
||||
confPath: String,
|
||||
},
|
||||
computed: {
|
||||
sections() {
|
||||
return this.$store.getters.sections;
|
||||
|
@ -27,7 +30,22 @@ const HomeMixin = {
|
|||
data: () => ({
|
||||
searchValue: '',
|
||||
}),
|
||||
async mounted() {
|
||||
await this.getConfigForRoute();
|
||||
},
|
||||
watch: {
|
||||
async $route() {
|
||||
await this.getConfigForRoute();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async getConfigForRoute() {
|
||||
if (this.confPath) { // Get config for sub-page
|
||||
await this.$store.dispatch(Keys.INITIALIZE_MULTI_PAGE_CONFIG, this.confPath);
|
||||
} else { // Otherwise, use main config
|
||||
this.$store.commit(Keys.USE_MAIN_CONFIG);
|
||||
}
|
||||
},
|
||||
updateModalVisibility(modalState) {
|
||||
this.$store.commit('SET_MODAL_OPEN', modalState);
|
||||
},
|
||||
|
|
|
@ -11,10 +11,13 @@ import { Progress } from 'rsup-progress';
|
|||
|
||||
// Import views, that are not lazy-loaded
|
||||
import Home from '@/views/Home.vue';
|
||||
// import Workspace from '@/views/Workspace.vue';
|
||||
// import Minimal from '@/views/Minimal.vue';
|
||||
import ConfigAccumulator from '@/utils/ConfigAccumalator';
|
||||
|
||||
// Import helper functions, config data and defaults
|
||||
import { isAuthEnabled, isLoggedIn, isGuestAccessEnabled } from '@/utils/Auth';
|
||||
import { makePageSlug } from '@/utils/ConfigHelpers';
|
||||
import { metaTagData, startingView, routePaths } from '@/utils/defaults';
|
||||
import ErrorHandler from '@/utils/ErrorHandler';
|
||||
|
||||
|
@ -64,19 +67,33 @@ const makeMetaTags = (defaultTitle) => ({
|
|||
metaTags: metaTagData,
|
||||
});
|
||||
|
||||
const makePageSlug = (pageName) => {
|
||||
const formattedName = pageName.toLowerCase().replaceAll(' ', '-');
|
||||
return `/${formattedName}`;
|
||||
const makeSubConfigPath = (rawPath) => {
|
||||
if (rawPath.startsWith('/') || rawPath.startsWith('http')) return rawPath;
|
||||
else return `/${rawPath}`;
|
||||
};
|
||||
|
||||
/* For each additional config file, create routes for home, minimal and workspace views */
|
||||
const makeMultiPageRoutes = (userPages) => {
|
||||
if (!userPages) return [];
|
||||
const multiPageRoutes = [];
|
||||
userPages.forEach((page) => {
|
||||
multiPageRoutes.push({
|
||||
path: makePageSlug(page.name),
|
||||
name: page.name,
|
||||
path: makePageSlug(page.name, 'home'),
|
||||
name: `${page.name}-home`,
|
||||
component: Home,
|
||||
props: { confPath: makeSubConfigPath(page.path) },
|
||||
});
|
||||
multiPageRoutes.push({
|
||||
path: makePageSlug(page.name, 'workspace'),
|
||||
name: `${page.name}-workspace`,
|
||||
component: () => import('./views/Workspace.vue'),
|
||||
props: { confPath: makeSubConfigPath(page.path) },
|
||||
});
|
||||
multiPageRoutes.push({
|
||||
path: makePageSlug(page.name, 'minimal'),
|
||||
name: `${page.name}-minimal`,
|
||||
component: () => import('./views/Minimal.vue'),
|
||||
props: { confPath: makeSubConfigPath(page.path) },
|
||||
});
|
||||
});
|
||||
return multiPageRoutes;
|
||||
|
|
24
src/store.js
24
src/store.js
|
@ -8,13 +8,14 @@ import ConfigAccumulator from '@/utils/ConfigAccumalator';
|
|||
import { componentVisibility } from '@/utils/ConfigHelpers';
|
||||
import { applyItemId } from '@/utils/SectionHelpers';
|
||||
import filterUserSections from '@/utils/CheckSectionVisibility';
|
||||
import { InfoHandler, InfoKeys } from '@/utils/ErrorHandler';
|
||||
import ErrorHandler, { InfoHandler, InfoKeys } from '@/utils/ErrorHandler';
|
||||
import { isUserAdmin } from '@/utils/Auth';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
const {
|
||||
INITIALIZE_CONFIG,
|
||||
INITIALIZE_MULTI_PAGE_CONFIG,
|
||||
SET_CONFIG,
|
||||
SET_REMOTE_CONFIG,
|
||||
SET_MODAL_OPEN,
|
||||
|
@ -24,6 +25,7 @@ const {
|
|||
SET_THEME,
|
||||
SET_CUSTOM_COLORS,
|
||||
UPDATE_ITEM,
|
||||
USE_MAIN_CONFIG,
|
||||
SET_EDIT_MODE,
|
||||
SET_PAGE_INFO,
|
||||
SET_APP_CONFIG,
|
||||
|
@ -59,6 +61,9 @@ const store = new Vuex.Store({
|
|||
sections(state) {
|
||||
return filterUserSections(state.config.sections || []);
|
||||
},
|
||||
pages(state) {
|
||||
return state.remoteConfig.pages || [];
|
||||
},
|
||||
theme(state) {
|
||||
return state.config.appConfig.theme;
|
||||
},
|
||||
|
@ -275,6 +280,13 @@ const store = new Vuex.Store({
|
|||
[CONF_MENU_INDEX](state, index) {
|
||||
state.navigateConfToTab = index;
|
||||
},
|
||||
[USE_MAIN_CONFIG](state) {
|
||||
if (state.remoteConfig) {
|
||||
state.config = state.remoteConfig;
|
||||
} else {
|
||||
this.dispatch(Keys.INITIALIZE_CONFIG);
|
||||
}
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/* Called when app first loaded. Reads config and sets state */
|
||||
|
@ -285,6 +297,16 @@ const store = new Vuex.Store({
|
|||
const config = deepCopy(new ConfigAccumulator().config());
|
||||
commit(SET_CONFIG, config);
|
||||
},
|
||||
/* Fetch config for a sub-page (sections and pageInfo only) */
|
||||
async [INITIALIZE_MULTI_PAGE_CONFIG]({ commit, state }, configPath) {
|
||||
axios.get(configPath).then((response) => {
|
||||
const subConfig = yaml.load(response.data);
|
||||
subConfig.appConfig = state.config.appConfig; // Always use parent appConfig
|
||||
commit(SET_CONFIG, subConfig);
|
||||
}).catch((err) => {
|
||||
ErrorHandler(`Unable to load config from '${configPath}'`, err);
|
||||
});
|
||||
},
|
||||
},
|
||||
modules: {},
|
||||
});
|
||||
|
|
|
@ -10,6 +10,12 @@ import {
|
|||
import ErrorHandler from '@/utils/ErrorHandler';
|
||||
import ConfigSchema from '@/utils/ConfigSchema.json';
|
||||
|
||||
/* For a given sub-page, and page type, return the URL */
|
||||
export const makePageSlug = (pageName, pageType) => {
|
||||
const formattedName = pageName.toLowerCase().replaceAll(' ', '-').replaceAll('.yml', '');
|
||||
return `/${pageType}/${formattedName}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initiates the Accumulator class and generates a complete config object
|
||||
* Self-executing function, returns the full user config as a JSON object
|
||||
|
|
|
@ -33,7 +33,7 @@ const setSwStatus = (swStateToSet) => {
|
|||
* Or disable if user specified to disable
|
||||
*/
|
||||
const shouldEnableServiceWorker = async () => {
|
||||
const conf = yaml.load((await axios.get('conf.yml')).data);
|
||||
const conf = yaml.load((await axios.get('/conf.yml')).data);
|
||||
if (conf && conf.appConfig && conf.appConfig.enableServiceWorker) {
|
||||
setSwStatus({ disabledByUser: false });
|
||||
return true;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// A list of mutation names
|
||||
const KEY_NAMES = [
|
||||
'INITIALIZE_CONFIG',
|
||||
'INITIALIZE_MULTI_PAGE_CONFIG',
|
||||
'SET_CONFIG',
|
||||
'SET_REMOTE_CONFIG',
|
||||
'SET_MODAL_OPEN',
|
||||
|
@ -10,6 +11,7 @@ const KEY_NAMES = [
|
|||
'SET_ITEM_SIZE',
|
||||
'SET_THEME',
|
||||
'SET_CUSTOM_COLORS',
|
||||
'USE_MAIN_CONFIG',
|
||||
'UPDATE_ITEM',
|
||||
'SET_PAGE_INFO',
|
||||
'SET_APP_CONFIG',
|
||||
|
|
Loading…
Reference in New Issue