mirror of
https://github.com/Lissy93/dashy.git
synced 2025-07-27 15:44:27 +02:00
Work in progress, config re-write (#799)
This commit is contained in:
parent
e9ff44ac91
commit
6be38b9f58
@ -36,7 +36,7 @@ const HomeMixin = {
|
|||||||
searchValue: '',
|
searchValue: '',
|
||||||
}),
|
}),
|
||||||
async mounted() {
|
async mounted() {
|
||||||
await this.getConfigForRoute();
|
// await this.getConfigForRoute();
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
async $route() {
|
async $route() {
|
||||||
@ -44,15 +44,27 @@ const HomeMixin = {
|
|||||||
this.setTheme();
|
this.setTheme();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
async created() {
|
||||||
|
// console.log(this.$router.currentRoute.path);
|
||||||
|
const subPage = this.determineConfigFile();
|
||||||
|
await this.$store.dispatch(Keys.INITIALIZE_CONFIG, subPage);
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getConfigForRoute() {
|
/* Based on the current route, get which config to display, null will use default */
|
||||||
this.$store.commit(Keys.SET_CURRENT_SUB_PAGE, this.subPageInfo);
|
determineConfigFile() {
|
||||||
if (this.subPageInfo && this.subPageInfo.confPath) { // Get config for sub-page
|
const pagePath = this.$router.currentRoute.path;
|
||||||
await this.$store.dispatch(Keys.INITIALIZE_MULTI_PAGE_CONFIG, this.subPageInfo.confPath);
|
const isSubPage = new RegExp((/(home|workspace|minimal)\/[a-zA-Z0-9-]+/g)).test(pagePath);
|
||||||
} else { // Otherwise, use main config
|
const subPageName = isSubPage ? pagePath.split('/').pop() : null;
|
||||||
this.$store.commit(Keys.USE_MAIN_CONFIG);
|
return subPageName;
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
// async getConfigForRoute() {
|
||||||
|
// this.$store.commit(Keys.SET_CURRENT_SUB_PAGE, this.subPageInfo);
|
||||||
|
// if (this.subPageInfo && this.subPageInfo.confPath) { // Get config for sub-page
|
||||||
|
// await this.$store.dispatch(Keys.INITIALIZE_MULTI_PAGE_CONFIG, this.subPageInfo.confPath);
|
||||||
|
// } else { // Otherwise, use main config
|
||||||
|
// this.$store.commit(Keys.USE_MAIN_CONFIG);
|
||||||
|
// }
|
||||||
|
// },
|
||||||
/* TEMPORARY: If on sub-page, check if custom theme is set and return it */
|
/* TEMPORARY: If on sub-page, check if custom theme is set and return it */
|
||||||
getSubPageTheme() {
|
getSubPageTheme() {
|
||||||
if (!this.pageId || this.pageId === 'home') {
|
if (!this.pageId || this.pageId === 'home') {
|
||||||
|
@ -14,7 +14,7 @@ import Home from '@/views/Home.vue';
|
|||||||
|
|
||||||
// Import helper functions, config data and defaults
|
// Import helper functions, config data and defaults
|
||||||
import { isAuthEnabled, isLoggedIn, isGuestAccessEnabled } from '@/utils/Auth';
|
import { isAuthEnabled, isLoggedIn, isGuestAccessEnabled } from '@/utils/Auth';
|
||||||
import { makePageSlug, makePageName } from '@/utils/ConfigHelpers';
|
// import { makePageSlug, makePageName } from '@/utils/ConfigHelpers';
|
||||||
import { metaTagData, startingView, routePaths } from '@/utils/defaults';
|
import { metaTagData, startingView, routePaths } from '@/utils/defaults';
|
||||||
import ErrorHandler from '@/utils/ErrorHandler';
|
import ErrorHandler from '@/utils/ErrorHandler';
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ if (!conf) {
|
|||||||
|
|
||||||
// Assign top-level config fields, check not null
|
// Assign top-level config fields, check not null
|
||||||
const config = conf || {};
|
const config = conf || {};
|
||||||
const pages = config.pages || [];
|
// const pages = config.pages || [];
|
||||||
const pageInfo = config.pageInfo || {};
|
const pageInfo = config.pageInfo || {};
|
||||||
const appConfig = config.appConfig || {};
|
const appConfig = config.appConfig || {};
|
||||||
|
|
||||||
@ -64,54 +64,54 @@ const makeMetaTags = (defaultTitle) => ({
|
|||||||
metaTags: metaTagData,
|
metaTags: metaTagData,
|
||||||
});
|
});
|
||||||
|
|
||||||
const makeSubConfigPath = (rawPath) => {
|
// const makeSubConfigPath = (rawPath) => {
|
||||||
if (!rawPath) return '';
|
// if (!rawPath) return '';
|
||||||
if (rawPath.startsWith('/') || rawPath.startsWith('http')) return rawPath;
|
// if (rawPath.startsWith('/') || rawPath.startsWith('http')) return rawPath;
|
||||||
else return `/${rawPath}`;
|
// else return `/${rawPath}`;
|
||||||
};
|
// };
|
||||||
|
|
||||||
/* For each additional config file, create routes for home, minimal and workspace views */
|
/* For each additional config file, create routes for home, minimal and workspace views */
|
||||||
const makeMultiPageRoutes = (userPages) => {
|
// const makeMultiPageRoutes = (userPages) => {
|
||||||
// If no multi pages specified, or is not array, then return nothing
|
// // If no multi pages specified, or is not array, then return nothing
|
||||||
if (!userPages || !Array.isArray(userPages)) return [];
|
// if (!userPages || !Array.isArray(userPages)) return [];
|
||||||
const multiPageRoutes = [];
|
// const multiPageRoutes = [];
|
||||||
// For each user page, create an additional route
|
// // For each user page, create an additional route
|
||||||
userPages.forEach((page) => {
|
// userPages.forEach((page) => {
|
||||||
if (!page.name || !page.path) { // Sumin not right, show warning
|
// if (!page.name || !page.path) { // Sumin not right, show warning
|
||||||
ErrorHandler('Additional pages must have both a `name` and `path`');
|
// ErrorHandler('Additional pages must have both a `name` and `path`');
|
||||||
}
|
// }
|
||||||
// Props to be passed to home mixin
|
// // Props to be passed to home mixin
|
||||||
const subPageInfo = {
|
// const subPageInfo = {
|
||||||
subPageInfo: {
|
// subPageInfo: {
|
||||||
confPath: makeSubConfigPath(page.path),
|
// confPath: makeSubConfigPath(page.path),
|
||||||
pageId: makePageName(page.name),
|
// pageId: makePageName(page.name),
|
||||||
pageTitle: page.name,
|
// pageTitle: page.name,
|
||||||
},
|
// },
|
||||||
};
|
// };
|
||||||
// Create route for default homepage
|
// // Create route for default homepage
|
||||||
multiPageRoutes.push({
|
// multiPageRoutes.push({
|
||||||
path: makePageSlug(page.name, 'home'),
|
// path: makePageSlug(page.name, 'home'),
|
||||||
name: `${subPageInfo.subPageInfo.pageId}-home`,
|
// name: `${subPageInfo.subPageInfo.pageId}-home`,
|
||||||
component: Home,
|
// component: Home,
|
||||||
props: subPageInfo,
|
// props: subPageInfo,
|
||||||
});
|
// });
|
||||||
// Create route for the workspace view
|
// // Create route for the workspace view
|
||||||
multiPageRoutes.push({
|
// multiPageRoutes.push({
|
||||||
path: makePageSlug(page.name, 'workspace'),
|
// path: makePageSlug(page.name, 'workspace'),
|
||||||
name: `${subPageInfo.subPageInfo.pageId}-workspace`,
|
// name: `${subPageInfo.subPageInfo.pageId}-workspace`,
|
||||||
component: () => import('./views/Workspace.vue'),
|
// component: () => import('./views/Workspace.vue'),
|
||||||
props: subPageInfo,
|
// props: subPageInfo,
|
||||||
});
|
// });
|
||||||
// Create route for the minimal view
|
// // Create route for the minimal view
|
||||||
multiPageRoutes.push({
|
// multiPageRoutes.push({
|
||||||
path: makePageSlug(page.name, 'minimal'),
|
// path: makePageSlug(page.name, 'minimal'),
|
||||||
name: `${subPageInfo.subPageInfo.pageId}-minimal`,
|
// name: `${subPageInfo.subPageInfo.pageId}-minimal`,
|
||||||
component: () => import('./views/Minimal.vue'),
|
// component: () => import('./views/Minimal.vue'),
|
||||||
props: subPageInfo,
|
// props: subPageInfo,
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
return multiPageRoutes;
|
// return multiPageRoutes;
|
||||||
};
|
// };
|
||||||
|
|
||||||
/* Routing mode, can be either 'hash', 'history' or 'abstract' */
|
/* Routing mode, can be either 'hash', 'history' or 'abstract' */
|
||||||
const mode = appConfig.routingMode || 'history';
|
const mode = appConfig.routingMode || 'history';
|
||||||
@ -120,7 +120,7 @@ const mode = appConfig.routingMode || 'history';
|
|||||||
const router = new Router({
|
const router = new Router({
|
||||||
mode,
|
mode,
|
||||||
routes: [
|
routes: [
|
||||||
...makeMultiPageRoutes(pages),
|
// ...makeMultiPageRoutes(pages),
|
||||||
{ // The default view can be customized by the user
|
{ // The default view can be customized by the user
|
||||||
path: '/',
|
path: '/',
|
||||||
name: `landing-page-${getStartingView()}`,
|
name: `landing-page-${getStartingView()}`,
|
||||||
|
68
src/store.js
68
src/store.js
@ -4,7 +4,7 @@ import Vuex from 'vuex';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import Keys from '@/utils/StoreMutations';
|
import Keys from '@/utils/StoreMutations';
|
||||||
import ConfigAccumulator from '@/utils/ConfigAccumalator';
|
// import ConfigAccumulator from '@/utils/ConfigAccumalator';
|
||||||
import { componentVisibility } from '@/utils/ConfigHelpers';
|
import { componentVisibility } from '@/utils/ConfigHelpers';
|
||||||
import { applyItemId } from '@/utils/SectionHelpers';
|
import { applyItemId } from '@/utils/SectionHelpers';
|
||||||
import filterUserSections from '@/utils/CheckSectionVisibility';
|
import filterUserSections from '@/utils/CheckSectionVisibility';
|
||||||
@ -16,8 +16,10 @@ Vue.use(Vuex);
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
INITIALIZE_CONFIG,
|
INITIALIZE_CONFIG,
|
||||||
INITIALIZE_MULTI_PAGE_CONFIG,
|
INITIALIZE_ROOT_CONFIG,
|
||||||
|
// INITIALIZE_MULTI_PAGE_CONFIG,
|
||||||
SET_CONFIG,
|
SET_CONFIG,
|
||||||
|
SET_ROOT_CONFIG,
|
||||||
SET_REMOTE_CONFIG,
|
SET_REMOTE_CONFIG,
|
||||||
SET_CURRENT_SUB_PAGE,
|
SET_CURRENT_SUB_PAGE,
|
||||||
SET_MODAL_OPEN,
|
SET_MODAL_OPEN,
|
||||||
@ -46,7 +48,8 @@ const {
|
|||||||
const store = new Vuex.Store({
|
const store = new Vuex.Store({
|
||||||
state: {
|
state: {
|
||||||
config: {}, // The current config, rendered to the UI
|
config: {}, // The current config, rendered to the UI
|
||||||
remoteConfig: {}, // The configuration stored on the server
|
rootConfig: null, // The config from the main config file
|
||||||
|
// remoteConfig: {}, // The configuration stored on the server
|
||||||
editMode: false, // While true, the user can drag and edit items + sections
|
editMode: false, // While true, the user can drag and edit items + sections
|
||||||
modalOpen: false, // KB shortcut functionality will be disabled when modal is open
|
modalOpen: false, // KB shortcut functionality will be disabled when modal is open
|
||||||
currentConfigInfo: undefined, // For multi-page support, will store info about config file
|
currentConfigInfo: undefined, // For multi-page support, will store info about config file
|
||||||
@ -68,7 +71,7 @@ const store = new Vuex.Store({
|
|||||||
return filterUserSections(state.config.sections || []);
|
return filterUserSections(state.config.sections || []);
|
||||||
},
|
},
|
||||||
pages(state) {
|
pages(state) {
|
||||||
return state.remoteConfig.pages || [];
|
return state.config.pages || [];
|
||||||
},
|
},
|
||||||
theme(state) {
|
theme(state) {
|
||||||
let localTheme = null;
|
let localTheme = null;
|
||||||
@ -145,6 +148,10 @@ const store = new Vuex.Store({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
|
[SET_ROOT_CONFIG](state, config) {
|
||||||
|
if (!config.appConfig) config.appConfig = {};
|
||||||
|
state.config = config;
|
||||||
|
},
|
||||||
[SET_CONFIG](state, config) {
|
[SET_CONFIG](state, config) {
|
||||||
if (!config.appConfig) config.appConfig = {};
|
if (!config.appConfig) config.appConfig = {};
|
||||||
state.config = config;
|
state.config = config;
|
||||||
@ -323,24 +330,43 @@ const store = new Vuex.Store({
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
/* Called when app first loaded. Reads config and sets state */
|
/* Called when app first loaded. Reads config and sets state */
|
||||||
async [INITIALIZE_CONFIG]({ commit }) {
|
// async [INITIALIZE_CONFIG]({ commit }) {
|
||||||
// Get the config file from the server and store it for use by the accumulator
|
// // Get the config file from the server and store it for use by the accumulator
|
||||||
commit(SET_REMOTE_CONFIG, yaml.load((await axios.get('/conf.yml')).data));
|
// commit(SET_REMOTE_CONFIG, yaml.load((await axios.get('/conf.yml')).data));
|
||||||
const deepCopy = (json) => JSON.parse(JSON.stringify(json));
|
// const deepCopy = (json) => JSON.parse(JSON.stringify(json));
|
||||||
const config = deepCopy(new ConfigAccumulator().config());
|
// const config = deepCopy(new ConfigAccumulator().config());
|
||||||
commit(SET_CONFIG, config);
|
// commit(SET_CONFIG, config);
|
||||||
|
// },
|
||||||
|
/* Fetches the root config file, only ever called by INITIALIZE_CONFIG */
|
||||||
|
async [INITIALIZE_ROOT_CONFIG]({ commit }) {
|
||||||
|
console.log('Initializing root config....');
|
||||||
|
commit(SET_ROOT_CONFIG, yaml.load((await axios.get('/conf.yml')).data));
|
||||||
},
|
},
|
||||||
/* Fetch config for a sub-page (sections and pageInfo only) */
|
/**
|
||||||
async [INITIALIZE_MULTI_PAGE_CONFIG]({ commit, state }, configPath) {
|
* Fetches config and updates state
|
||||||
axios.get(configPath).then((response) => {
|
* If not on sub-page, will trigger the fetch of main config, then use that
|
||||||
const subConfig = yaml.load(response.data);
|
* If using sub-page config, then fetch that sub-config, then
|
||||||
const pageTheme = subConfig.appConfig?.theme;
|
* override certain fields (appConfig, pages) and update config
|
||||||
subConfig.appConfig = state.config.appConfig; // Always use parent appConfig
|
*/
|
||||||
if (pageTheme) subConfig.appConfig.theme = pageTheme; // Apply page theme override
|
async [INITIALIZE_CONFIG]({ commit, state }, subConfigPath) {
|
||||||
commit(SET_CONFIG, subConfig);
|
const fetchPath = subConfigPath || '/conf.yml'; // The path to fetch config from
|
||||||
}).catch((err) => {
|
if (!state.rootConfig) {
|
||||||
ErrorHandler(`Unable to load config from '${configPath}'`, err);
|
await this.dispatch(Keys.INITIALIZE_ROOT_CONFIG);
|
||||||
});
|
}
|
||||||
|
console.log('rootConfig', state.rootConfig);
|
||||||
|
if (!subConfigPath) { // Use root config as config
|
||||||
|
commit(SET_CONFIG, state.rootConfig);
|
||||||
|
} else { // Fetch sub-config, and use as config
|
||||||
|
axios.get(fetchPath).then((response) => {
|
||||||
|
const configContent = yaml.load(response.data);
|
||||||
|
// Certain values must be inherited from root config
|
||||||
|
configContent.appConfig = state.rootConfig.appConfig;
|
||||||
|
configContent.pages = state.rootConfig.pages;
|
||||||
|
commit(SET_CONFIG, configContent);
|
||||||
|
}).catch((err) => {
|
||||||
|
ErrorHandler(`Unable to load config from '${fetchPath}'`, err);
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
modules: {},
|
modules: {},
|
||||||
|
@ -20,7 +20,7 @@ import buildConf from '../../public/conf.yml';
|
|||||||
|
|
||||||
export default class ConfigAccumulator {
|
export default class ConfigAccumulator {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.conf = $store.state.remoteConfig;
|
this.conf = $store.state.config;
|
||||||
}
|
}
|
||||||
|
|
||||||
pages() {
|
pages() {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
// A list of mutation names
|
// A list of mutation names
|
||||||
const KEY_NAMES = [
|
const KEY_NAMES = [
|
||||||
'INITIALIZE_CONFIG',
|
'INITIALIZE_CONFIG',
|
||||||
|
'INITIALIZE_ROOT_CONFIG',
|
||||||
'INITIALIZE_MULTI_PAGE_CONFIG',
|
'INITIALIZE_MULTI_PAGE_CONFIG',
|
||||||
'SET_CONFIG',
|
'SET_CONFIG',
|
||||||
|
'SET_ROOT_CONFIG',
|
||||||
'SET_REMOTE_CONFIG',
|
'SET_REMOTE_CONFIG',
|
||||||
'SET_CURRENT_SUB_PAGE',
|
'SET_CURRENT_SUB_PAGE',
|
||||||
'SET_MODAL_OPEN',
|
'SET_MODAL_OPEN',
|
||||||
|
@ -28,9 +28,9 @@ module.exports = {
|
|||||||
openingMethod: 'newtab',
|
openingMethod: 'newtab',
|
||||||
/* The page paths for each route within the app for the router */
|
/* The page paths for each route within the app for the router */
|
||||||
routePaths: {
|
routePaths: {
|
||||||
home: '/home',
|
home: '/home/:config?/',
|
||||||
minimal: '/minimal',
|
minimal: '/minimal/:config?/',
|
||||||
workspace: '/workspace',
|
workspace: '/workspace/:config?/',
|
||||||
about: '/about',
|
about: '/about',
|
||||||
login: '/login',
|
login: '/login',
|
||||||
download: '/download',
|
download: '/download',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user