mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
feat(editor): Add Workflow history route and base page (no-changelog) (#7161)
This commit is contained in:
parent
556a6132ba
commit
240b2f075e
|
@ -324,6 +324,7 @@ export class Server extends AbstractServer {
|
||||||
externalSecrets: false,
|
externalSecrets: false,
|
||||||
showNonProdBanner: false,
|
showNonProdBanner: false,
|
||||||
debugInEditor: false,
|
debugInEditor: false,
|
||||||
|
workflowHistory: false,
|
||||||
},
|
},
|
||||||
mfa: {
|
mfa: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
|
|
@ -383,6 +383,7 @@ export const enum VIEWS {
|
||||||
SOURCE_CONTROL = 'SourceControl',
|
SOURCE_CONTROL = 'SourceControl',
|
||||||
AUDIT_LOGS = 'AuditLogs',
|
AUDIT_LOGS = 'AuditLogs',
|
||||||
MFA_VIEW = 'MfaView',
|
MFA_VIEW = 'MfaView',
|
||||||
|
WORKFLOW_HISTORY = 'WorkflowHistory',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum FAKE_DOOR_FEATURES {
|
export const enum FAKE_DOOR_FEATURES {
|
||||||
|
@ -454,6 +455,7 @@ export const enum EnterpriseEditionFeature {
|
||||||
ExternalSecrets = 'externalSecrets',
|
ExternalSecrets = 'externalSecrets',
|
||||||
AuditLogs = 'auditLogs',
|
AuditLogs = 'auditLogs',
|
||||||
DebugInEditor = 'debugInEditor',
|
DebugInEditor = 'debugInEditor',
|
||||||
|
WorkflowHistory = 'workflowHistory',
|
||||||
}
|
}
|
||||||
export const MAIN_NODE_PANEL_WIDTH = 360;
|
export const MAIN_NODE_PANEL_WIDTH = 360;
|
||||||
|
|
||||||
|
|
|
@ -1753,6 +1753,7 @@
|
||||||
"workflowSettings.timeoutAfter": "Timeout After",
|
"workflowSettings.timeoutAfter": "Timeout After",
|
||||||
"workflowSettings.timeoutWorkflow": "Timeout Workflow",
|
"workflowSettings.timeoutWorkflow": "Timeout Workflow",
|
||||||
"workflowSettings.timezone": "Timezone",
|
"workflowSettings.timezone": "Timezone",
|
||||||
|
"workflowHistory.title": "Version History",
|
||||||
"workflows.heading": "Workflows",
|
"workflows.heading": "Workflows",
|
||||||
"workflows.add": "Add Workflow",
|
"workflows.add": "Add Workflow",
|
||||||
"workflows.menu.my": "My workflows",
|
"workflows.menu.my": "My workflows",
|
||||||
|
|
|
@ -40,6 +40,7 @@ import SamlOnboarding from '@/views/SamlOnboarding.vue';
|
||||||
import SettingsSourceControl from './views/SettingsSourceControl.vue';
|
import SettingsSourceControl from './views/SettingsSourceControl.vue';
|
||||||
import SettingsExternalSecrets from './views/SettingsExternalSecrets.vue';
|
import SettingsExternalSecrets from './views/SettingsExternalSecrets.vue';
|
||||||
import SettingsAuditLogs from './views/SettingsAuditLogs.vue';
|
import SettingsAuditLogs from './views/SettingsAuditLogs.vue';
|
||||||
|
import WorkflowHistory from '@/views/WorkflowHistory.vue';
|
||||||
import { EnterpriseEditionFeature, VIEWS } from '@/constants';
|
import { EnterpriseEditionFeature, VIEWS } from '@/constants';
|
||||||
|
|
||||||
interface IRouteConfig {
|
interface IRouteConfig {
|
||||||
|
@ -293,6 +294,28 @@ export const routes = [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/workflow/:workflowId/history/:historyId?',
|
||||||
|
name: VIEWS.WORKFLOW_HISTORY,
|
||||||
|
components: {
|
||||||
|
default: WorkflowHistory,
|
||||||
|
sidebar: MainSidebar,
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
keepWorkflowAlive: true,
|
||||||
|
permissions: {
|
||||||
|
allow: {
|
||||||
|
loginStatus: [LOGIN_STATUS.LoggedIn],
|
||||||
|
},
|
||||||
|
deny: {
|
||||||
|
shouldDeny: () =>
|
||||||
|
!useSettingsStore().isEnterpriseFeatureEnabled(
|
||||||
|
EnterpriseEditionFeature.WorkflowHistory,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/workflows/templates/:id',
|
path: '/workflows/templates/:id',
|
||||||
name: VIEWS.TEMPLATE_IMPORT,
|
name: VIEWS.TEMPLATE_IMPORT,
|
||||||
|
@ -493,7 +516,7 @@ export const routes = [
|
||||||
shouldDeny: () => {
|
shouldDeny: () => {
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
return (
|
return (
|
||||||
settingsStore.settings.hideUsagePage === true ||
|
settingsStore.settings.hideUsagePage ||
|
||||||
settingsStore.settings.deployment?.type === 'cloud'
|
settingsStore.settings.deployment?.type === 'cloud'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -570,7 +593,7 @@ export const routes = [
|
||||||
deny: {
|
deny: {
|
||||||
shouldDeny: () => {
|
shouldDeny: () => {
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
return settingsStore.isPublicApiEnabled === false;
|
return !settingsStore.isPublicApiEnabled;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -685,7 +708,7 @@ export const routes = [
|
||||||
deny: {
|
deny: {
|
||||||
shouldDeny: () => {
|
shouldDeny: () => {
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
return settingsStore.isCommunityNodesFeatureEnabled === false;
|
return !settingsStore.isCommunityNodesFeatureEnabled;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -702,7 +725,7 @@ export const routes = [
|
||||||
pageCategory: 'settings',
|
pageCategory: 'settings',
|
||||||
getProperties(route: RouteLocation) {
|
getProperties(route: RouteLocation) {
|
||||||
return {
|
return {
|
||||||
feature: route.params['featureId'],
|
feature: route.params.featureId,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
56
packages/editor-ui/src/views/WorkflowHistory.vue
Normal file
56
packages/editor-ui/src/views/WorkflowHistory.vue
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useI18n } from '@/composables';
|
||||||
|
|
||||||
|
const i18n = useI18n();
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div :class="$style.view">
|
||||||
|
<n8n-heading :class="$style.header" tag="h2" size="medium" bold>Workflow name</n8n-heading>
|
||||||
|
<div :class="$style.corner">
|
||||||
|
<n8n-heading tag="h2" size="medium" bold>{{
|
||||||
|
i18n.baseText('workflowHistory.title')
|
||||||
|
}}</n8n-heading>
|
||||||
|
<n8n-button type="tertiary" icon="times" size="small" text square />
|
||||||
|
</div>
|
||||||
|
<div :class="$style.content"></div>
|
||||||
|
<div :class="$style.list"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style module lang="scss">
|
||||||
|
.view {
|
||||||
|
display: grid;
|
||||||
|
width: 100%;
|
||||||
|
grid-template-areas: 'header corner' 'content list';
|
||||||
|
grid-template-columns: auto 330px;
|
||||||
|
grid-template-rows: 65px auto;
|
||||||
|
background-color: var(--color-background-xlight);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
grid-area: header;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 var(--spacing-l);
|
||||||
|
border-bottom: var(--border-width-base) var(--border-style-base) var(--color-foreground-base);
|
||||||
|
}
|
||||||
|
|
||||||
|
.corner {
|
||||||
|
grid-area: corner;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 var(--spacing-3xs) 0 var(--spacing-s);
|
||||||
|
background-color: var(--color-background-lighter);
|
||||||
|
border-bottom: var(--border-width-base) var(--border-style-base) var(--color-foreground-base);
|
||||||
|
border-left: var(--border-width-base) var(--border-style-base) var(--color-foreground-base);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
grid-area: content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
grid-area: list;
|
||||||
|
border-left: var(--border-width-base) var(--border-style-base) var(--color-foreground-base);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -2186,6 +2186,7 @@ export interface IN8nUISettings {
|
||||||
externalSecrets: boolean;
|
externalSecrets: boolean;
|
||||||
showNonProdBanner: boolean;
|
showNonProdBanner: boolean;
|
||||||
debugInEditor: boolean;
|
debugInEditor: boolean;
|
||||||
|
workflowHistory: boolean;
|
||||||
};
|
};
|
||||||
hideUsagePage: boolean;
|
hideUsagePage: boolean;
|
||||||
license: {
|
license: {
|
||||||
|
|
Loading…
Reference in a new issue