dashboard/shell/initialize/entry-helpers.js

148 lines
3.6 KiB
JavaScript

/**
* Add error handler debugging capabilities
* @param {*} vueApp Vue instance
*/
export const loadDebugger = (vueApp) => {
const debug = process.env.dev;
if (debug) {
const defaultErrorHandler = vueApp.config.errorHandler;
vueApp.config.errorHandler = async(err, vm, info, ...rest) => {
// Call other handler if exist
let handled = null;
if (typeof defaultErrorHandler === 'function') {
handled = defaultErrorHandler(err, vm, info, ...rest);
}
if (handled === true) {
return handled;
}
if (vm && vm.$root) {
const globalApp = Object.keys(window.$globalApp)
.find((instance) => vm.$root[instance]);
// Show Error Page
if (globalApp && vm.$root[globalApp].error && info !== 'render function') {
const vueApp = vm.$root[globalApp];
vueApp.error(err);
}
}
if (typeof defaultErrorHandler === 'function') {
return handled;
}
// Log to console
if (process.env.NODE_ENV !== 'production') {
console.error(err); // eslint-disable-line no-console
} else {
console.error(err.message || err); // eslint-disable-line no-console
}
};
}
};
/**
* Mounts the Vue app to the DOM element
* @param {Object} appPartials - App view partials
* @param {Object} vueApp- Vue instance
*/
export async function mountApp(appPartials, vueApp) {
// Set global variables
const app = appPartials.app;
const router = appPartials.router;
vueApp.use(router);
vueApp.use(app.store);
vueApp.$loading = {}; // To avoid error while vueApp.$loading does not exist
vueApp.mount('#app');
}
export const getMatchedComponents = (route, matches = false, prop = 'components') => {
return Array.prototype.concat.apply([], route.matched.map((match, index) => {
return Object.keys(match[prop]).map((key) => {
matches && matches.push(index);
return match[prop][key];
});
}));
};
/**
* Merge route meta with component meta and update matched components
* @param {*} route
* @returns
*/
export const getRouteData = async(route) => {
if (!route) {
return;
}
// Ensure we're working with the _value property of the route object
const routeValue = route._value || route;
if (!routeValue.matched) {
// eslint-disable-next-line no-console
console.warn('Route matched property is undefined:', routeValue);
return routeValue;
}
const meta = routeValue.matched.map((record) => {
// Merge component meta and route record meta
const componentMeta = record.components?.default?.meta || {};
const recordMeta = record.meta || {};
return { ...componentMeta, ...recordMeta };
});
return {
...routeValue,
meta
};
};
/**
* Add missing context for the Vue instance
* @param {*} app
* @param {*} context
*/
export const setContext = async(app, context) => {
// If context not defined, create it
if (!app.context) {
app.context = {
isDev: true,
app,
store: app.store,
payload: context.payload,
error: context.error,
base: app.router.options.base,
};
// Only set once
}
// Dynamic keys
const [currentRouteData, fromRouteData] = await Promise.all([
getRouteData(context.route),
getRouteData(context.from)
]);
if (context.route) {
app.context.route = currentRouteData;
}
if (context.from) {
app.context.from = fromRouteData;
}
app.context.next = context.next;
app.context._redirected = false;
app.context.params = app.context.route?.params || {};
app.context.query = app.context.route?.query || {};
};