feat: Version control mvp (#6271)

* implement basic git service

* cleanup connected prop

* add skeleton of git functions

* initial import/export setup

* split out export service

* refactor and improve export

* begin import

* more commands and basic import

* clean up imports with transactions

* work folder import functions

* reintroduce versionid

* add missing import to pull workfolder

* add get-status endpoint

* add cleanup to disconnect

* add initRepo options

* add more checks and cleanup

* minor cleanup

* refactor prefs

* fix server.ts

* fix sending deleted files

* rename files to ee

* add variable override and fix critical cred import bug

* fix mkdir race condition

* make initRepo default to true

* fix front back integration

* improve connect flow

* add comment to generated ssh key

* fix(editor): use useToast composable

* fix buttons size

* commenting out repo init for now

* fix(editor): update UI logic

* fix(editor): remove console.log

* fix(editor): remove unused ref

* adjust endpoints for improved UI

* fix(editor): add push and pull buttons

* keep or not ssh key

* switching file name to id

* fix(editor): add success messages, fix save button

* fixed faulty diff preventing pull

* fix build

* fix(editor): adding loader to VC components

* removing duplicate exports

* improve conflict finding on push pull

* manage pull conflict

* alternate push pull

* fix pull confirmation

* fix rm and credential export/import

* switch to alternative pull implementation

* fix initial commit

* fix(editor): subscribing to VC store action to refresh lists

* fix(editor): wrap VC store actions with try

* feat: add fine-grained file selection for push action

* fix: close modal after successful push

* fix(editor): VC preferences validation

* fix confirm

* fix: update endpoint to /get-status

* feat: update pull modal override changes message

* fix missing wf error

* undo

* removing connect endpoint

* fix(editor): add button titles

* fix(editor): cleaning up store action

* add version-control/set-read-only protection

* fix(editor): adding set branch readonly

* fix(editor): remove Push button if branch set to readonly

* fix(editor): fix some styles

* fix(editor): remove duplicate and delete actions in WF list when branch is readonly

* fix: load status before opening selective push modal

* fix(editor): extend readonly logic

* add cleanup after failed initRepo

* fix deleted files crashing get-status

* fix n8n-checkbox in staging dialog

* fix(editor): fix loading

* fix(editor): resize buttons

* fix(editor): fix translation

* fix(editor): fix copy text size

* fix(editor): fix copy text size

* fix(editor): add disconnection confirmation

* fix(editor): add disconnection confirmation

* fix(editor): set large buttons

* add public api Pull endpoint

* feat: add refresh ssh key

* return prefs when new keys are generated

* fix(editor): adding readOnly mode to main header

* fix(editor): adding readOnly mode to workflow settings

* improve credential owner import

* add middleware to endpoints

* improve public api error/doc

* do not create branch if one already exists

* update wordings for connect toasts

* fix(editor): updating and separating readonly modes

* fix(editor): fix readonly mode in WF list

* fix(editor): disable elements dragging on canvas in readonly mode (WIP: not working when NodeView page is loaded first)

* fix(editor): fix canvas draggables in readonly env

* fix(editor): remove unused variables

* fix(editor): hide actions in node connections when readonly

* fix(editor): hide actions in node connections when readonly

* fix(editor): disable Save button when readonly

* fix(editor): disable Save settings if no branch is selected

* fix(editor): lint fix

* fix(editor): update snapshots

* fix(editor): replace Loading... text

* fix(editor): reset Loading... text

* reset branchname on disconnect

* fix(editor): adding some translations

* fix(editor): fix unit test

* fix(editor): fix loading

* fix(editor): set settings saved message

* fix(editor): update connection flag

* fix branchName not returning after connect

* temporary (but still breaking) fix for postgres

* fix(editor): adding tooltip to Push/Pull buttons when they're collapsed

* fix(editor): enabled activator in readonly mode

* fix test

* fix(editor): disabling new item addition for workflows in readonly mode

* fix(editor): modify Pull/Push button tooltips

* do not commit empty variables file

---------

Co-authored-by: Michael Auerswald <michael.auerswald@gmail.com>
Co-authored-by: Romain Minaud <romain.minaud@gmail.com>
Co-authored-by: Alex Grozav <alex@grozav.com>
This commit is contained in:
Csaba Tuncsik
2023-05-31 15:01:57 +02:00
committed by GitHub
parent 04cfa548af
commit 1b321416c0
75 changed files with 3720 additions and 460 deletions

View File

@@ -14,6 +14,7 @@
:previewValue="shortenedName"
:isEditEnabled="isNameEditEnabled"
:maxLength="MAX_WORKFLOW_NAME_LENGTH"
:disabled="readOnly"
@toggle="onNameToggle"
@submit="onNameSubmit"
placeholder="Enter workflow name"
@@ -25,7 +26,7 @@
</BreakpointsObserver>
<span v-if="settingsStore.areTagsEnabled" class="tags" data-test-id="workflow-tags-container">
<div v-if="isTagsEditEnabled">
<div v-if="isTagsEditEnabled && !readOnly">
<TagsDropdown
:createEnabled="true"
:currentTagIds="appliedTagIds"
@@ -39,7 +40,7 @@
data-test-id="workflow-tags-dropdown"
/>
</div>
<div v-else-if="currentWorkflowTagIds.length === 0">
<div v-else-if="currentWorkflowTagIds.length === 0 && !readOnly">
<span class="add-tag clickable" data-test-id="new-tag-link" @click="onTagsEditEnable">
+ {{ $locale.baseText('workflowDetails.addTag') }}
</span>
@@ -99,7 +100,7 @@
<SaveButton
type="primary"
:saved="!this.isDirty && !this.isNewWorkflow"
:disabled="isWorkflowSaving"
:disabled="isWorkflowSaving || readOnly"
data-test-id="workflow-save-button"
@click="onSaveButtonClick"
/>
@@ -152,15 +153,17 @@ import type { IUser, IWorkflowDataUpdate, IWorkflowDb, IWorkflowToShare } from '
import { saveAs } from 'file-saver';
import { useTitleChange, useToast, useMessage } from '@/composables';
import type { MessageBoxInputData } from 'element-ui/types/message-box';
import { useUIStore } from '@/stores/ui.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useRootStore } from '@/stores/n8nRoot.store';
import { useTagsStore } from '@/stores/tags.store';
import {
useUIStore,
useSettingsStore,
useWorkflowsStore,
useRootStore,
useTagsStore,
useUsersStore,
useUsageStore,
} from '@/stores';
import type { IPermissions } from '@/permissions';
import { getWorkflowPermissions } from '@/permissions';
import { useUsersStore } from '@/stores/users.store';
import { useUsageStore } from '@/stores/usage.store';
import { createEventBus } from 'n8n-design-system';
import { useCloudPlanStore } from '@/stores';
@@ -186,6 +189,12 @@ export default defineComponent({
InlineTextEdit,
BreakpointsObserver,
},
props: {
readOnly: {
type: Boolean,
default: false,
},
},
setup() {
return {
...useTitleChange(),
@@ -266,44 +275,52 @@ export default defineComponent({
return getWorkflowPermissions(this.usersStore.currentUser, this.workflow);
},
workflowMenuItems(): Array<{}> {
return [
{
id: WORKFLOW_MENU_ACTIONS.DUPLICATE,
label: this.$locale.baseText('menuActions.duplicate'),
disabled: !this.onWorkflowPage || !this.currentWorkflowId,
},
const actions = [
{
id: WORKFLOW_MENU_ACTIONS.DOWNLOAD,
label: this.$locale.baseText('menuActions.download'),
disabled: !this.onWorkflowPage,
},
{
id: WORKFLOW_MENU_ACTIONS.IMPORT_FROM_URL,
label: this.$locale.baseText('menuActions.importFromUrl'),
disabled: !this.onWorkflowPage || this.onExecutionsTab,
},
{
id: WORKFLOW_MENU_ACTIONS.IMPORT_FROM_FILE,
label: this.$locale.baseText('menuActions.importFromFile'),
disabled: !this.onWorkflowPage || this.onExecutionsTab,
},
{
id: WORKFLOW_MENU_ACTIONS.SETTINGS,
label: this.$locale.baseText('generic.settings'),
disabled: !this.onWorkflowPage || this.isNewWorkflow,
},
...(this.workflowPermissions.delete
? [
{
id: WORKFLOW_MENU_ACTIONS.DELETE,
label: this.$locale.baseText('menuActions.delete'),
disabled: !this.onWorkflowPage || this.isNewWorkflow,
customClass: this.$style.deleteItem,
divided: true,
},
]
: []),
];
if (!this.readOnly) {
actions.unshift({
id: WORKFLOW_MENU_ACTIONS.DUPLICATE,
label: this.$locale.baseText('menuActions.duplicate'),
disabled: !this.onWorkflowPage || !this.currentWorkflowId,
});
actions.push(
{
id: WORKFLOW_MENU_ACTIONS.IMPORT_FROM_URL,
label: this.$locale.baseText('menuActions.importFromUrl'),
disabled: !this.onWorkflowPage || this.onExecutionsTab,
},
{
id: WORKFLOW_MENU_ACTIONS.IMPORT_FROM_FILE,
label: this.$locale.baseText('menuActions.importFromFile'),
disabled: !this.onWorkflowPage || this.onExecutionsTab,
},
);
}
actions.push({
id: WORKFLOW_MENU_ACTIONS.SETTINGS,
label: this.$locale.baseText('generic.settings'),
disabled: !this.onWorkflowPage || this.isNewWorkflow,
});
if (this.workflowPermissions.delete && !this.readOnly) {
actions.push({
id: WORKFLOW_MENU_ACTIONS.DELETE,
label: this.$locale.baseText('menuActions.delete'),
disabled: !this.onWorkflowPage || this.isNewWorkflow,
customClass: this.$style.deleteItem,
divided: true,
});
}
return actions;
},
},
methods: {