feat(editor): Version Control settings update (WIP) (#6233)

This commit is contained in:
Csaba Tuncsik 2023-05-12 09:26:41 +02:00 committed by GitHub
parent 51c89db6dc
commit 0666377ef8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 156 additions and 66 deletions

View file

@ -1438,7 +1438,8 @@ export type VersionControlPreferences = {
repositoryUrl: string;
authorName: string;
authorEmail: string;
branchName: string;
currentBranch: string;
branches: string[];
branchReadOnly: boolean;
branchColor: string;
publicKey?: string;

View file

@ -1290,18 +1290,26 @@
"settings.versionControl.actionBox.title": "Available on Enterprise plan",
"settings.versionControl.actionBox.description": "Use Version Control to connect your instance to an external Git repository to backup and track changes made to your workflows, variables, and credentials. With Version Control you can also sync instances across multiple environments (development, production...).",
"settings.versionControl.actionBox.buttonText": "See plans",
"settings.versionControl.description": "Versioning allows you to connect your n8n instance to a Git branch of a repository. You can connect your branches to multiples n8n instances to create a multi environments setup. Learn how to set up versioning and environments in n8n.",
"settings.versionControl.repoUrl": "Git repository URL",
"settings.versionControl.description": "Versioning allows you to connect your n8n instance to a Git branch of a repository. You can connect your branches to multiples n8n instances to create a multi environments setup. {link}",
"settings.versionControl.description.link": "Learn how to set up versioning and environments in n8n.",
"settings.versionControl.gitConfig": "Git configuration",
"settings.versionControl.repoUrl": "Git repository URL (SSH)",
"settings.versionControl.repoUrlPlaceholder": "e.g. git@github.com:my-team/my-repository",
"settings.versionControl.repoUrlDescription": "The SSH url of your Git repository",
"settings.versionControl.authorName": "Author name",
"settings.versionControl.authorEmail": "Author email",
"settings.versionControl.authorName": "Commit author name",
"settings.versionControl.authorEmail": "Commit author email",
"settings.versionControl.sshKey": "SSH Key",
"settings.versionControl.sshKeyDescription": "Paste the SSH key in yout git repository settings. {link}.",
"settings.versionControl.sshKeyDescriptionLink": "More info.",
"settings.versionControl.button.continue": "Continue",
"settings.versionControl.button.connect": "Connect",
"settings.versionControl.branches": "Select branch",
"settings.versionControl.button.save": "Save settings",
"settings.versionControl.instanceSettings": "Instance settings",
"settings.versionControl.branches": "Branch connected to this n8n instance",
"settings.versionControl.readonly": "{bold}: prevent editing workflows (recommended for production environments). {link}",
"settings.versionControl.readonly.bold": "Read-only instance",
"settings.versionControl.readonly.link": "Learn more.",
"settings.versionControl.color": "Color",
"settings.versionControl.switchBranch.title": "Switch to {branch} branch",
"settings.versionControl.switchBranch.description": "Please confirm you want to switch the current n8n instance to the branch: {branch}",
"settings.versionControl.sync.prompt.title": "Sync changes in {branch} branch",

View file

@ -16,12 +16,13 @@ export const useVersionControlStore = defineStore('versionControl', () => {
);
const preferences = reactive<VersionControlPreferences>({
branchName: '',
currentBranch: '',
branches: [],
authorName: '',
authorEmail: '',
repositoryUrl: '',
branchReadOnly: false,
branchColor: '#000000',
branchColor: '#F4A6DC',
connected: false,
publicKey: '',
});
@ -77,6 +78,7 @@ export const useVersionControlStore = defineStore('versionControl', () => {
return {
isEnterpriseVersionControlEnabled,
state,
preferences,
initSsh,
initRepository,
sync,

View file

@ -1,19 +1,14 @@
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { i18n as locale } from '@/plugins/i18n';
import { useVersionControlStore } from '@/stores/versionControl.store';
import { useUIStore } from '@/stores/ui.store';
import { useMessage } from '@/composables';
import CopyInput from '@/components/CopyInput.vue';
const versionControlStore = useVersionControlStore();
const uiStore = useUIStore();
const message = useMessage();
const sshKey = computed(() => versionControlStore.state.sshKey);
const branch = computed(() => versionControlStore.state.currentBranch);
const branches = ref<string[]>([]);
const selectElement = ref<HTMLSelectElement | null>(null);
const onContinue = () => {
void versionControlStore.initSsh({
name: versionControlStore.state.authorName,
@ -26,22 +21,15 @@ const onConnect = () => {
void versionControlStore.initRepository();
};
const onSave = () => {
void versionControlStore.savePreferences(versionControlStore.preferences);
};
const onSelect = async (b: string) => {
if (b === branch.value) {
if (b === versionControlStore.preferences.currentBranch) {
return;
}
const switchBranch = await message
.confirm(
locale.baseText('settings.versionControl.switchBranch.description', {
interpolate: { branch: b },
}),
locale.baseText('settings.versionControl.switchBranch.title', { interpolate: { branch: b } }),
)
.catch(() => {});
if (switchBranch === 'confirm') {
versionControlStore.state.currentBranch = b;
selectElement.value?.blur();
}
versionControlStore.preferences.currentBranch = b;
};
const goToUpgrade = () => {
@ -51,40 +39,59 @@ const goToUpgrade = () => {
<template>
<div>
<n8n-heading size="2xlarge">{{ locale.baseText('settings.versionControl.title') }}</n8n-heading>
<n8n-heading size="2xlarge" tag="h1">{{
locale.baseText('settings.versionControl.title')
}}</n8n-heading>
<div
v-if="versionControlStore.isEnterpriseVersionControlEnabled"
data-test-id="version-control-content-licensed"
>
<n8n-callout theme="secondary" icon="info-circle" class="mt-2xl mb-l">{{
locale.baseText('settings.versionControl.description')
}}</n8n-callout>
<n8n-callout theme="secondary" icon="info-circle" class="mt-2xl mb-l">
<i18n path="settings.versionControl.description">
<template #link>
<a href="#" target="_blank">
{{ locale.baseText('settings.versionControl.description.link') }}
</a>
</template>
</i18n>
</n8n-callout>
<n8n-heading size="xlarge" tag="h2" class="mb-s">{{
locale.baseText('settings.versionControl.gitConfig')
}}</n8n-heading>
<div :class="$style.group">
<label for="repoUrl">{{ locale.baseText('settings.versionControl.repoUrl') }}</label>
<n8n-input
id="repoUrl"
:placeholder="locale.baseText('settings.versionControl.repoUrlPlaceholder')"
v-model="versionControlStore.state.repositoryUrl"
v-model="versionControlStore.preferences.repositoryUrl"
/>
<small>{{ locale.baseText('settings.versionControl.repoUrlDescription') }}</small>
</div>
<div :class="$style.group">
<label for="authorName">{{ locale.baseText('settings.versionControl.authorName') }}</label>
<n8n-input id="authorName" v-model="versionControlStore.state.authorName" />
<div :class="[$style.group, $style.groupFlex]">
<div>
<label for="authorName">{{
locale.baseText('settings.versionControl.authorName')
}}</label>
<n8n-input id="authorName" v-model="versionControlStore.preferences.authorName" />
</div>
<div>
<label for="authorEmail">{{
locale.baseText('settings.versionControl.authorEmail')
}}</label>
<n8n-input id="authorEmail" v-model="versionControlStore.preferences.authorEmail" />
</div>
</div>
<div :class="$style.group">
<label for="authorEmail">{{
locale.baseText('settings.versionControl.authorEmail')
}}</label>
<n8n-input id="authorEmail" v-model="versionControlStore.state.authorEmail" />
</div>
<n8n-button v-if="!sshKey" @click="onContinue" size="large" class="mt-2xs">{{
locale.baseText('settings.versionControl.button.continue')
}}</n8n-button>
<div v-if="sshKey" :class="$style.group">
<n8n-button
v-if="!versionControlStore.preferences.publicKey"
@click="onContinue"
size="large"
class="mt-2xs"
>{{ locale.baseText('settings.versionControl.button.continue') }}</n8n-button
>
<div v-if="versionControlStore.preferences.publicKey" :class="$style.group">
<label>{{ locale.baseText('settings.versionControl.sshKey') }}</label>
<CopyInput
:value="versionControlStore.state.sshKey"
:value="versionControlStore.preferences.publicKey"
:copy-button-text="locale.baseText('generic.clickToCopy')"
/>
<n8n-notice type="info" class="mt-s">
@ -97,25 +104,70 @@ const goToUpgrade = () => {
</i18n>
</n8n-notice>
</div>
<n8n-button v-if="sshKey" @click="onConnect" size="large" :class="$style.connect">{{
locale.baseText('settings.versionControl.button.connect')
}}</n8n-button>
<div v-if="versionControlStore.state.branches.length" :class="$style.group">
<label>{{ locale.baseText('settings.versionControl.branches') }}</label>
<n8n-select
ref="selectElement"
:value="versionControlStore.state.currentBranch"
size="medium"
filterable
@input="onSelect"
>
<n8n-option
v-for="b in versionControlStore.state.branches"
:key="b"
:value="b"
:label="b"
/>
</n8n-select>
<n8n-button
v-if="
versionControlStore.preferences.publicKey &&
!versionControlStore.preferences.branches.length
"
@click="onConnect"
size="large"
:class="$style.connect"
>{{ locale.baseText('settings.versionControl.button.connect') }}</n8n-button
>
<div v-if="versionControlStore.preferences.branches.length">
<div :class="$style.group">
<hr />
<n8n-heading size="xlarge" tag="h2" class="mb-s">{{
locale.baseText('settings.versionControl.instanceSettings')
}}</n8n-heading>
<label>{{ locale.baseText('settings.versionControl.branches') }}</label>
<n8n-select
:value="versionControlStore.preferences.currentBranch"
class="mb-s"
size="medium"
filterable
@input="onSelect"
>
<n8n-option
v-for="b in versionControlStore.preferences.branches"
:key="b"
:value="b"
:label="b"
/>
</n8n-select>
<n8n-checkbox
v-model="versionControlStore.preferences.branchReadOnly"
:class="$style.readOnly"
>
<i18n path="settings.versionControl.readonly">
<template #bold>
<strong>{{ locale.baseText('settings.versionControl.readonly.bold') }}</strong>
</template>
<template #link>
<a href="#" target="_blank">
{{ locale.baseText('settings.versionControl.readonly.link') }}
</a>
</template>
</i18n>
</n8n-checkbox>
</div>
<div :class="$style.group">
<label>{{ locale.baseText('settings.versionControl.color') }}</label>
<div>
<n8n-color-picker size="small" v-model="versionControlStore.preferences.branchColor" />
</div>
</div>
<div :class="[$style.group, 'pt-s']">
<n8n-button
v-if="
versionControlStore.preferences.publicKey &&
versionControlStore.preferences.currentBranch
"
@click="onSave"
size="large"
>{{ locale.baseText('settings.versionControl.button.save') }}</n8n-button
>
</div>
</div>
</div>
<n8n-action-box
@ -135,7 +187,7 @@ const goToUpgrade = () => {
<style lang="scss" module>
.group {
padding: 0 0 var(--spacing-2xs);
padding: 0 0 var(--spacing-s);
label {
display: inline-block;
@ -151,6 +203,28 @@ const goToUpgrade = () => {
}
}
.readOnly {
span {
font-size: var(--font-size-s) !important;
}
}
.groupFlex {
display: flex;
> div {
flex: 1;
&:last-child {
margin-left: var(--spacing-2xs);
}
}
input {
width: 100%;
}
}
.connect {
margin: calc(var(--spacing-2xs) * -1) 0 var(--spacing-2xs);
}
@ -158,4 +232,9 @@ const goToUpgrade = () => {
.actionBox {
margin: var(--spacing-2xl) 0 0;
}
hr {
margin: 0 0 var(--spacing-xl);
border: 1px solid var(--color-foreground-light);
}
</style>