mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-16 01:24:05 -08:00
675 lines
14 KiB
TypeScript
675 lines
14 KiB
TypeScript
import Vue from 'vue';
|
|
|
|
import ChangePasswordView from './views/ChangePasswordView.vue';
|
|
import ErrorView from './views/ErrorView.vue';
|
|
import ForgotMyPasswordView from './views/ForgotMyPasswordView.vue';
|
|
import MainHeader from '@/components/MainHeader/MainHeader.vue';
|
|
import MainSidebar from '@/components/MainSidebar.vue';
|
|
import NodeView from '@/views/NodeView.vue';
|
|
import WorkflowExecutionsList from '@/components/ExecutionsView/ExecutionsList.vue';
|
|
import ExecutionsLandingPage from '@/components/ExecutionsView/ExecutionsLandingPage.vue';
|
|
import ExecutionPreview from '@/components/ExecutionsView/ExecutionPreview.vue';
|
|
import SettingsView from './views/SettingsView.vue';
|
|
import SettingsLdapView from './views/SettingsLdapView.vue';
|
|
import SettingsPersonalView from './views/SettingsPersonalView.vue';
|
|
import SettingsUsersView from './views/SettingsUsersView.vue';
|
|
import SettingsCommunityNodesView from './views/SettingsCommunityNodesView.vue';
|
|
import SettingsApiView from './views/SettingsApiView.vue';
|
|
import SettingsLogStreamingView from './views/SettingsLogStreamingView.vue';
|
|
import SettingsFakeDoorView from './views/SettingsFakeDoorView.vue';
|
|
import SetupView from './views/SetupView.vue';
|
|
import SigninView from './views/SigninView.vue';
|
|
import SignupView from './views/SignupView.vue';
|
|
import Router, { Route } from 'vue-router';
|
|
|
|
import TemplatesCollectionView from '@/views/TemplatesCollectionView.vue';
|
|
import TemplatesWorkflowView from '@/views/TemplatesWorkflowView.vue';
|
|
import TemplatesSearchView from '@/views/TemplatesSearchView.vue';
|
|
import CredentialsView from '@/views/CredentialsView.vue';
|
|
import ExecutionsView from '@/views/ExecutionsView.vue';
|
|
import WorkflowsView from '@/views/WorkflowsView.vue';
|
|
import { IPermissions } from './Interface';
|
|
import { LOGIN_STATUS, ROLE } from '@/utils';
|
|
import { RouteConfigSingleView } from 'vue-router/types/router';
|
|
import { EnterpriseEditionFeature, VIEWS } from './constants';
|
|
import { useSettingsStore } from './stores/settings';
|
|
import { useTemplatesStore } from './stores/templates';
|
|
import SettingsUsageAndPlanVue from './views/SettingsUsageAndPlan.vue';
|
|
import SignoutView from '@/views/SignoutView.vue';
|
|
|
|
Vue.use(Router);
|
|
|
|
interface IRouteConfig extends RouteConfigSingleView {
|
|
meta: {
|
|
nodeView?: boolean;
|
|
templatesEnabled?: boolean;
|
|
getRedirect?: () => { name: string } | false;
|
|
permissions: IPermissions;
|
|
telemetry?: {
|
|
disabled?: true;
|
|
getProperties: (route: Route) => object;
|
|
};
|
|
scrollOffset?: number;
|
|
};
|
|
}
|
|
|
|
function getTemplatesRedirect() {
|
|
const settingsStore = useSettingsStore();
|
|
const isTemplatesEnabled: boolean = settingsStore.isTemplatesEnabled;
|
|
if (!isTemplatesEnabled) {
|
|
return { name: VIEWS.NOT_FOUND };
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
const router = new Router({
|
|
mode: 'history',
|
|
base: import.meta.env.DEV ? '/' : window.BASE_PATH ?? '/',
|
|
scrollBehavior(to, from, savedPosition) {
|
|
// saved position == null means the page is NOT visited from history (back button)
|
|
if (savedPosition === null && to.name === VIEWS.TEMPLATES && to.meta) {
|
|
// for templates view, reset scroll position in this case
|
|
to.meta.setScrollPosition(0);
|
|
}
|
|
},
|
|
routes: [
|
|
{
|
|
path: '/',
|
|
name: VIEWS.HOMEPAGE,
|
|
meta: {
|
|
getRedirect() {
|
|
return { name: VIEWS.WORKFLOWS };
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/collections/:id',
|
|
name: VIEWS.COLLECTION,
|
|
components: {
|
|
default: TemplatesCollectionView,
|
|
sidebar: MainSidebar,
|
|
},
|
|
meta: {
|
|
templatesEnabled: true,
|
|
telemetry: {
|
|
getProperties(route: Route) {
|
|
const templatesStore = useTemplatesStore();
|
|
return {
|
|
collection_id: route.params.id,
|
|
wf_template_repo_session_id: templatesStore.currentSessionId,
|
|
};
|
|
},
|
|
},
|
|
getRedirect: getTemplatesRedirect,
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/templates/:id',
|
|
name: VIEWS.TEMPLATE,
|
|
components: {
|
|
default: TemplatesWorkflowView,
|
|
sidebar: MainSidebar,
|
|
},
|
|
meta: {
|
|
templatesEnabled: true,
|
|
getRedirect: getTemplatesRedirect,
|
|
telemetry: {
|
|
getProperties(route: Route) {
|
|
const templatesStore = useTemplatesStore();
|
|
return {
|
|
template_id: route.params.id,
|
|
wf_template_repo_session_id: templatesStore.currentSessionId,
|
|
};
|
|
},
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/templates/',
|
|
name: VIEWS.TEMPLATES,
|
|
components: {
|
|
default: TemplatesSearchView,
|
|
sidebar: MainSidebar,
|
|
},
|
|
meta: {
|
|
templatesEnabled: true,
|
|
getRedirect: getTemplatesRedirect,
|
|
// Templates view remembers it's scroll position on back
|
|
scrollOffset: 0,
|
|
telemetry: {
|
|
getProperties(route: Route) {
|
|
const templatesStore = useTemplatesStore();
|
|
return {
|
|
wf_template_repo_session_id: templatesStore.currentSessionId,
|
|
};
|
|
},
|
|
},
|
|
setScrollPosition(pos: number) {
|
|
this.scrollOffset = pos;
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/credentials',
|
|
name: VIEWS.CREDENTIALS,
|
|
components: {
|
|
default: CredentialsView,
|
|
sidebar: MainSidebar,
|
|
},
|
|
meta: {
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/executions',
|
|
name: VIEWS.EXECUTIONS,
|
|
components: {
|
|
default: ExecutionsView,
|
|
sidebar: MainSidebar,
|
|
},
|
|
meta: {
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/workflow',
|
|
redirect: '/workflow/new',
|
|
},
|
|
{
|
|
path: '/workflows',
|
|
name: VIEWS.WORKFLOWS,
|
|
components: {
|
|
default: WorkflowsView,
|
|
sidebar: MainSidebar,
|
|
},
|
|
meta: {
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/workflow/new',
|
|
name: VIEWS.NEW_WORKFLOW,
|
|
components: {
|
|
default: NodeView,
|
|
header: MainHeader,
|
|
sidebar: MainSidebar,
|
|
},
|
|
meta: {
|
|
nodeView: true,
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/workflow/:name',
|
|
name: VIEWS.WORKFLOW,
|
|
components: {
|
|
default: NodeView,
|
|
header: MainHeader,
|
|
sidebar: MainSidebar,
|
|
},
|
|
meta: {
|
|
nodeView: true,
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/workflow/:name/executions',
|
|
name: VIEWS.WORKFLOW_EXECUTIONS,
|
|
components: {
|
|
default: WorkflowExecutionsList,
|
|
header: MainHeader,
|
|
sidebar: MainSidebar,
|
|
},
|
|
meta: {
|
|
keepWorkflowAlive: true,
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
children: [
|
|
{
|
|
path: '',
|
|
name: VIEWS.EXECUTION_HOME,
|
|
components: {
|
|
executionPreview: ExecutionsLandingPage,
|
|
},
|
|
meta: {
|
|
keepWorkflowAlive: true,
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: ':executionId',
|
|
name: VIEWS.EXECUTION_PREVIEW,
|
|
components: {
|
|
executionPreview: ExecutionPreview,
|
|
},
|
|
meta: {
|
|
keepWorkflowAlive: true,
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
path: '/workflows/demo',
|
|
name: VIEWS.DEMO,
|
|
components: {
|
|
default: NodeView,
|
|
},
|
|
meta: {
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/workflows/templates/:id',
|
|
name: VIEWS.TEMPLATE_IMPORT,
|
|
components: {
|
|
default: NodeView,
|
|
header: MainHeader,
|
|
sidebar: MainSidebar,
|
|
},
|
|
meta: {
|
|
templatesEnabled: true,
|
|
getRedirect: getTemplatesRedirect,
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/signin',
|
|
name: VIEWS.SIGNIN,
|
|
components: {
|
|
default: SigninView,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'auth',
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedOut],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/signup',
|
|
name: VIEWS.SIGNUP,
|
|
components: {
|
|
default: SignupView,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'auth',
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedOut],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/signout',
|
|
name: VIEWS.SIGNOUT,
|
|
components: {
|
|
default: SignoutView,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'auth',
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/setup',
|
|
name: VIEWS.SETUP,
|
|
components: {
|
|
default: SetupView,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'auth',
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
role: [ROLE.Default],
|
|
},
|
|
deny: {
|
|
shouldDeny: () => {
|
|
const settingsStore = useSettingsStore();
|
|
return settingsStore.isUserManagementEnabled === false;
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/forgot-password',
|
|
name: VIEWS.FORGOT_PASSWORD,
|
|
components: {
|
|
default: ForgotMyPasswordView,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'auth',
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedOut],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/change-password',
|
|
name: VIEWS.CHANGE_PASSWORD,
|
|
components: {
|
|
default: ChangePasswordView,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'auth',
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedOut],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: '/settings',
|
|
component: SettingsView,
|
|
props: true,
|
|
children: [
|
|
{
|
|
path: 'usage',
|
|
name: VIEWS.USAGE,
|
|
components: {
|
|
settingsView: SettingsUsageAndPlanVue,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'settings',
|
|
getProperties(route: Route) {
|
|
return {
|
|
feature: 'usage',
|
|
};
|
|
},
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
deny: {
|
|
shouldDeny: () => {
|
|
const settingsStore = useSettingsStore();
|
|
return (
|
|
settingsStore.settings.hideUsagePage === true ||
|
|
settingsStore.settings.deployment?.type === 'cloud'
|
|
);
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: 'personal',
|
|
name: VIEWS.PERSONAL_SETTINGS,
|
|
components: {
|
|
settingsView: SettingsPersonalView,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'settings',
|
|
getProperties(route: Route) {
|
|
return {
|
|
feature: 'personal',
|
|
};
|
|
},
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
deny: {
|
|
role: [ROLE.Default],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: 'users',
|
|
name: VIEWS.USERS_SETTINGS,
|
|
components: {
|
|
settingsView: SettingsUsersView,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'settings',
|
|
getProperties(route: Route) {
|
|
return {
|
|
feature: 'users',
|
|
};
|
|
},
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
role: [ROLE.Default, ROLE.Owner],
|
|
},
|
|
deny: {
|
|
shouldDeny: () => {
|
|
const settingsStore = useSettingsStore();
|
|
|
|
return (
|
|
settingsStore.isUserManagementEnabled === false &&
|
|
!(settingsStore.isCloudDeployment || settingsStore.isDesktopDeployment)
|
|
);
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: 'api',
|
|
name: VIEWS.API_SETTINGS,
|
|
components: {
|
|
settingsView: SettingsApiView,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'settings',
|
|
getProperties(route: Route) {
|
|
return {
|
|
feature: 'api',
|
|
};
|
|
},
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
deny: {
|
|
shouldDeny: () => {
|
|
const settingsStore = useSettingsStore();
|
|
return settingsStore.isPublicApiEnabled === false;
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: 'log-streaming',
|
|
name: VIEWS.LOG_STREAMING_SETTINGS,
|
|
components: {
|
|
settingsView: SettingsLogStreamingView,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'settings',
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
role: [ROLE.Owner],
|
|
},
|
|
deny: {
|
|
role: [ROLE.Default],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: 'community-nodes',
|
|
name: VIEWS.COMMUNITY_NODES,
|
|
components: {
|
|
settingsView: SettingsCommunityNodesView,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'settings',
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
role: [ROLE.Default, ROLE.Owner],
|
|
},
|
|
deny: {
|
|
shouldDeny: () => {
|
|
const settingsStore = useSettingsStore();
|
|
return settingsStore.isCommunityNodesFeatureEnabled === false;
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: 'coming-soon/:featureId',
|
|
name: VIEWS.FAKE_DOOR,
|
|
components: {
|
|
settingsView: SettingsFakeDoorView,
|
|
},
|
|
meta: {
|
|
telemetry: {
|
|
pageCategory: 'settings',
|
|
getProperties(route: Route) {
|
|
return {
|
|
feature: route.params['featureId'],
|
|
};
|
|
},
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
path: 'ldap',
|
|
name: VIEWS.LDAP_SETTINGS,
|
|
components: {
|
|
settingsView: SettingsLdapView,
|
|
},
|
|
meta: {
|
|
permissions: {
|
|
allow: {
|
|
role: [ROLE.Owner],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
path: '*',
|
|
name: VIEWS.NOT_FOUND,
|
|
component: ErrorView,
|
|
props: {
|
|
messageKey: 'error.pageNotFound',
|
|
errorCode: 404,
|
|
redirectTextKey: 'error.goBack',
|
|
redirectPage: VIEWS.HOMEPAGE,
|
|
},
|
|
meta: {
|
|
nodeView: true,
|
|
telemetry: {
|
|
disabled: true,
|
|
},
|
|
permissions: {
|
|
allow: {
|
|
// TODO: Once custom permissions are merged, this needs to be updated with index validation
|
|
loginStatus: [LOGIN_STATUS.LoggedIn, LOGIN_STATUS.LoggedOut],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
] as IRouteConfig[],
|
|
});
|
|
|
|
export default router;
|