feat: Migrate integer primary keys to nanoids (#6345)
* first commit for postgres migration * (not working) * sqlite migration * quicksave * fix tests * fix pg test * fix postgres * fix variables import * fix execution saving * add user settings fix * change migration to single lines * patch preferences endpoint * cleanup * improve variable import * cleanup unusued code * Update packages/cli/src/PublicApi/v1/handlers/workflows/workflows.handler.ts Co-authored-by: Omar Ajoue <krynble@gmail.com> * address review notes * fix var update/import * refactor: Separate execution data to its own table (#6323) * wip: Temporary migration process * refactor: Create boilerplate repository methods for executions * fix: Lint issues * refactor: Added search endpoint to repository * refactor: Make the execution list work again * wip: Updating how we create and update executions everywhere * fix: Lint issues and remove most of the direct access to execution model * refactor: Remove includeWorkflowData flag and fix more tests * fix: Lint issues * fix: Fixed ordering of executions for FE, removed transaction when saving execution and removed unnecessary update * refactor: Add comment about missing feature * refactor: Refactor counting executions * refactor: Add migration for other dbms and fix issues found * refactor: Fix lint issues * refactor: Remove unnecessary comment and auto inject repo to internal hooks * refactor: remove type assertion * fix: Fix broken tests * fix: Remove unnecessary import * Remove unnecessary toString() call Co-authored-by: Iván Ovejero <ivov.src@gmail.com> * fix: Address comments after review * refactor: Remove unused import * fix: Lint issues * fix: Add correct migration files --------- Co-authored-by: Iván Ovejero <ivov.src@gmail.com> * remove null values from credential export * fix: Fix an issue with queue mode where all running execution would be returned * fix: Update n8n node to allow for workflow ids with letters * set upstream on set branch * remove typo * add nodeAccess to credentials * fix unsaved run check for undefined id * fix(core): Rename version control feature to source control (#6480) * rename versionControl to sourceControl * fix source control tooltip wording --------- Co-authored-by: Romain Minaud <romain.minaud@gmail.com> * fix(editor): Pay 548 hide the set up version control button (#6485) * feat(DebugHelper Node): Fix and include in main app (#6406) * improve node a bit * fixing continueOnFail() ton contain error in json * improve pairedItem * fix random data returning object results * fix nanoId length typo * update pnpm-lock file --------- Co-authored-by: Marcus <marcus@n8n.io> * fix(editor): Remove setup source control CTA button * fix(editor): Remove setup source control CTA button --------- Co-authored-by: Michael Auerswald <michael.auerswald@gmail.com> Co-authored-by: Marcus <marcus@n8n.io> * fix(editor): Update source control docs links (#6488) * feat(DebugHelper Node): Fix and include in main app (#6406) * improve node a bit * fixing continueOnFail() ton contain error in json * improve pairedItem * fix random data returning object results * fix nanoId length typo * update pnpm-lock file --------- Co-authored-by: Marcus <marcus@n8n.io> * feat(editor): Replace root events with event bus events (no-changelog) (#6454) * feat: replace root events with event bus events * fix: prevent cypress from replacing global with globalThis in import path * feat: remove emitter mixin * fix: replace component events with event bus * fix: fix linting issue * fix: fix breaking expression switch * chore: prettify ndv e2e suite code * fix(editor): Update source control docs links --------- Co-authored-by: Michael Auerswald <michael.auerswald@gmail.com> Co-authored-by: Marcus <marcus@n8n.io> Co-authored-by: Alex Grozav <alex@grozav.com> * fix tag endpoint regex --------- Co-authored-by: Omar Ajoue <krynble@gmail.com> Co-authored-by: Iván Ovejero <ivov.src@gmail.com> Co-authored-by: Romain Minaud <romain.minaud@gmail.com> Co-authored-by: Csaba Tuncsik <csaba@n8n.io> Co-authored-by: Marcus <marcus@n8n.io> Co-authored-by: Alex Grozav <alex@grozav.com>
This commit is contained in:
committed by
GitHub
parent
da330f0648
commit
c3ba0123ad
@@ -30,7 +30,7 @@ import {
|
||||
} from '@/constants';
|
||||
import type { INodeUi, ITabBarItem } from '@/Interface';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useUIStore, useNDVStore, useVersionControlStore } from '@/stores';
|
||||
import { useUIStore, useNDVStore, useSourceControlStore } from '@/stores';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'MainHeader',
|
||||
@@ -53,7 +53,7 @@ export default defineComponent({
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useNDVStore, useUIStore, useVersionControlStore),
|
||||
...mapStores(useNDVStore, useUIStore, useSourceControlStore),
|
||||
tabBarItems(): ITabBarItem[] {
|
||||
return [
|
||||
{ value: MAIN_HEADER_TABS.WORKFLOW, label: this.$locale.baseText('generic.editor') },
|
||||
@@ -82,7 +82,7 @@ export default defineComponent({
|
||||
return this.workflowsStore.activeWorkflowExecution as IExecutionsSummary;
|
||||
},
|
||||
readOnly(): boolean {
|
||||
return this.versionControlStore.preferences.branchReadOnly;
|
||||
return this.sourceControlStore.preferences.branchReadOnly;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
}}
|
||||
</n8n-text>
|
||||
</div>
|
||||
<MainSidebarVersionControl :is-collapsed="isCollapsed" />
|
||||
<MainSidebarSourceControl :is-collapsed="isCollapsed" />
|
||||
</div>
|
||||
</template>
|
||||
<template #footer v-if="showUserArea">
|
||||
@@ -120,18 +120,18 @@ import {
|
||||
useRootStore,
|
||||
useVersionsStore,
|
||||
useCloudPlanStore,
|
||||
useVersionControlStore,
|
||||
useSourceControlStore,
|
||||
} from '@/stores/';
|
||||
import { isNavigationFailure } from 'vue-router';
|
||||
import ExecutionsUsage from '@/components/ExecutionsUsage.vue';
|
||||
import MainSidebarVersionControl from '@/components/MainSidebarVersionControl.vue';
|
||||
import MainSidebarSourceControl from '@/components/MainSidebarSourceControl.vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'MainSidebar',
|
||||
components: {
|
||||
GiftNotificationIcon,
|
||||
ExecutionsUsage,
|
||||
MainSidebarVersionControl,
|
||||
MainSidebarSourceControl,
|
||||
},
|
||||
mixins: [genericHelpers, workflowHelpers, workflowRun, userHelpers, debounceHelper],
|
||||
setup(props) {
|
||||
@@ -155,7 +155,7 @@ export default defineComponent({
|
||||
useVersionsStore,
|
||||
useWorkflowsStore,
|
||||
useCloudPlanStore,
|
||||
useVersionControlStore,
|
||||
useSourceControlStore,
|
||||
),
|
||||
hasVersionUpdates(): boolean {
|
||||
return this.versionsStore.hasVersionUpdates;
|
||||
@@ -215,7 +215,7 @@ export default defineComponent({
|
||||
{
|
||||
id: 'workflows',
|
||||
icon: 'network-wired',
|
||||
secondaryIcon: this.versionControlStore.preferences.branchReadOnly
|
||||
secondaryIcon: this.sourceControlStore.preferences.branchReadOnly
|
||||
? { name: 'lock' }
|
||||
: undefined,
|
||||
label: this.$locale.baseText('mainSidebar.workflows'),
|
||||
|
||||
@@ -3,8 +3,8 @@ import { computed, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router/composables';
|
||||
import { createEventBus } from 'n8n-design-system/utils';
|
||||
import { useI18n, useLoadingService, useMessage, useToast } from '@/composables';
|
||||
import { useUIStore, useUsersStore, useVersionControlStore } from '@/stores';
|
||||
import { VERSION_CONTROL_PUSH_MODAL_KEY, VIEWS } from '@/constants';
|
||||
import { useUIStore, useSourceControlStore } from '@/stores';
|
||||
import { SOURCE_CONTROL_PUSH_MODAL_KEY, VIEWS } from '@/constants';
|
||||
|
||||
const props = defineProps<{
|
||||
isCollapsed: boolean;
|
||||
@@ -13,8 +13,7 @@ const props = defineProps<{
|
||||
const router = useRouter();
|
||||
const loadingService = useLoadingService();
|
||||
const uiStore = useUIStore();
|
||||
const versionControlStore = useVersionControlStore();
|
||||
const usersStore = useUsersStore();
|
||||
const sourceControlStore = useSourceControlStore();
|
||||
const message = useMessage();
|
||||
const toast = useToast();
|
||||
const { i18n } = useI18n();
|
||||
@@ -23,18 +22,18 @@ const eventBus = createEventBus();
|
||||
const tooltipOpenDelay = ref(300);
|
||||
|
||||
const currentBranch = computed(() => {
|
||||
return versionControlStore.preferences.branchName;
|
||||
return sourceControlStore.preferences.branchName;
|
||||
});
|
||||
const featureEnabled = computed(() => window.localStorage.getItem('version-control'));
|
||||
const featureEnabled = computed(() => window.localStorage.getItem('source-control'));
|
||||
const setupButtonTooltipPlacement = computed(() => (props.isCollapsed ? 'right' : 'top'));
|
||||
|
||||
async function pushWorkfolder() {
|
||||
loadingService.startLoading();
|
||||
try {
|
||||
const status = await versionControlStore.getAggregatedStatus();
|
||||
const status = await sourceControlStore.getAggregatedStatus();
|
||||
|
||||
uiStore.openModalWithData({
|
||||
name: VERSION_CONTROL_PUSH_MODAL_KEY,
|
||||
name: SOURCE_CONTROL_PUSH_MODAL_KEY,
|
||||
data: { eventBus, status },
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -47,25 +46,25 @@ async function pushWorkfolder() {
|
||||
|
||||
async function pullWorkfolder() {
|
||||
loadingService.startLoading();
|
||||
loadingService.setLoadingText(i18n.baseText('settings.versionControl.loading.pull'));
|
||||
loadingService.setLoadingText(i18n.baseText('settings.sourceControl.loading.pull'));
|
||||
try {
|
||||
await versionControlStore.pullWorkfolder(false);
|
||||
await sourceControlStore.pullWorkfolder(false);
|
||||
} catch (error) {
|
||||
const errorResponse = error.response;
|
||||
|
||||
if (errorResponse?.status === 409) {
|
||||
const confirm = await message.confirm(
|
||||
i18n.baseText('settings.versionControl.modals.pull.description'),
|
||||
i18n.baseText('settings.versionControl.modals.pull.title'),
|
||||
i18n.baseText('settings.sourceControl.modals.pull.description'),
|
||||
i18n.baseText('settings.sourceControl.modals.pull.title'),
|
||||
{
|
||||
confirmButtonText: i18n.baseText('settings.versionControl.modals.pull.buttons.save'),
|
||||
cancelButtonText: i18n.baseText('settings.versionControl.modals.pull.buttons.cancel'),
|
||||
confirmButtonText: i18n.baseText('settings.sourceControl.modals.pull.buttons.save'),
|
||||
cancelButtonText: i18n.baseText('settings.sourceControl.modals.pull.buttons.cancel'),
|
||||
},
|
||||
);
|
||||
|
||||
try {
|
||||
if (confirm === 'confirm') {
|
||||
await versionControlStore.pullWorkfolder(true);
|
||||
await sourceControlStore.pullWorkfolder(true);
|
||||
}
|
||||
} catch (error) {
|
||||
toast.showError(error, 'Error');
|
||||
@@ -79,8 +78,8 @@ async function pullWorkfolder() {
|
||||
}
|
||||
}
|
||||
|
||||
const goToVersionControlSetup = async () => {
|
||||
await router.push({ name: VIEWS.VERSION_CONTROL });
|
||||
const goToSourceControlSetup = async () => {
|
||||
await router.push({ name: VIEWS.SOURCE_CONTROL });
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -91,15 +90,15 @@ const goToVersionControlSetup = async () => {
|
||||
[$style.sync]: true,
|
||||
[$style.collapsed]: isCollapsed,
|
||||
[$style.isConnected]:
|
||||
versionControlStore.preferences.connected && versionControlStore.preferences.branchName,
|
||||
sourceControlStore.preferences.connected && sourceControlStore.preferences.branchName,
|
||||
}"
|
||||
:style="{ borderLeftColor: versionControlStore.preferences.branchColor }"
|
||||
data-test-id="main-sidebar-version-control"
|
||||
:style="{ borderLeftColor: sourceControlStore.preferences.branchColor }"
|
||||
data-test-id="main-sidebar-source-control"
|
||||
>
|
||||
<div
|
||||
v-if="versionControlStore.preferences.connected && versionControlStore.preferences.branchName"
|
||||
v-if="sourceControlStore.preferences.connected && sourceControlStore.preferences.branchName"
|
||||
:class="$style.connected"
|
||||
data-test-id="main-sidebar-version-control-connected"
|
||||
data-test-id="main-sidebar-source-control-connected"
|
||||
>
|
||||
<span>
|
||||
<n8n-icon icon="code-branch" />
|
||||
@@ -109,13 +108,13 @@ const goToVersionControlSetup = async () => {
|
||||
<n8n-tooltip :disabled="!isCollapsed" :open-delay="tooltipOpenDelay" placement="right">
|
||||
<template #content>
|
||||
<div>
|
||||
{{ i18n.baseText('settings.versionControl.button.pull') }}
|
||||
{{ i18n.baseText('settings.sourceControl.button.pull') }}
|
||||
</div>
|
||||
</template>
|
||||
<n8n-button
|
||||
:class="{
|
||||
'mr-2xs': !isCollapsed,
|
||||
'mb-2xs': isCollapsed && !versionControlStore.preferences.branchReadOnly,
|
||||
'mb-2xs': isCollapsed && !sourceControlStore.preferences.branchReadOnly,
|
||||
}"
|
||||
icon="arrow-down"
|
||||
type="tertiary"
|
||||
@@ -124,19 +123,19 @@ const goToVersionControlSetup = async () => {
|
||||
@click="pullWorkfolder"
|
||||
>
|
||||
<span v-if="!isCollapsed">{{
|
||||
i18n.baseText('settings.versionControl.button.pull')
|
||||
i18n.baseText('settings.sourceControl.button.pull')
|
||||
}}</span>
|
||||
</n8n-button>
|
||||
</n8n-tooltip>
|
||||
<n8n-tooltip
|
||||
v-if="!versionControlStore.preferences.branchReadOnly"
|
||||
v-if="!sourceControlStore.preferences.branchReadOnly"
|
||||
:disabled="!isCollapsed"
|
||||
:open-delay="tooltipOpenDelay"
|
||||
placement="right"
|
||||
>
|
||||
<template #content>
|
||||
<div>
|
||||
{{ i18n.baseText('settings.versionControl.button.push') }}
|
||||
{{ i18n.baseText('settings.sourceControl.button.push') }}
|
||||
</div>
|
||||
</template>
|
||||
<n8n-button
|
||||
@@ -147,35 +146,12 @@ const goToVersionControlSetup = async () => {
|
||||
@click="pushWorkfolder"
|
||||
>
|
||||
<span v-if="!isCollapsed">{{
|
||||
i18n.baseText('settings.versionControl.button.push')
|
||||
i18n.baseText('settings.sourceControl.button.push')
|
||||
}}</span>
|
||||
</n8n-button>
|
||||
</n8n-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<n8n-tooltip
|
||||
v-else-if="
|
||||
versionControlStore.isEnterpriseVersionControlEnabled && usersStore.isInstanceOwner
|
||||
"
|
||||
:open-delay="tooltipOpenDelay"
|
||||
:placement="setupButtonTooltipPlacement"
|
||||
data-test-id="main-sidebar-version-control-setup"
|
||||
>
|
||||
<template #content>
|
||||
<div>
|
||||
{{ i18n.baseText('settings.versionControl.button.setup.tooltip') }}
|
||||
</div>
|
||||
</template>
|
||||
<n8n-button
|
||||
icon="code-branch"
|
||||
type="tertiary"
|
||||
size="mini"
|
||||
:square="isCollapsed"
|
||||
@click="goToVersionControlSetup"
|
||||
>
|
||||
<span v-if="!isCollapsed">{{ i18n.baseText('settings.versionControl.button.setup') }}</span>
|
||||
</n8n-button>
|
||||
</n8n-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -112,9 +112,9 @@
|
||||
</template>
|
||||
</ModalRoot>
|
||||
|
||||
<ModalRoot :name="VERSION_CONTROL_PUSH_MODAL_KEY">
|
||||
<ModalRoot :name="SOURCE_CONTROL_PUSH_MODAL_KEY">
|
||||
<template #default="{ modalName, data }">
|
||||
<VersionControlPushModal :modalName="modalName" :data="data" />
|
||||
<SourceControlPushModal :modalName="modalName" :data="data" />
|
||||
</template>
|
||||
</ModalRoot>
|
||||
</div>
|
||||
@@ -145,7 +145,7 @@ import {
|
||||
IMPORT_CURL_MODAL_KEY,
|
||||
LOG_STREAM_MODAL_KEY,
|
||||
ASK_AI_MODAL_KEY,
|
||||
VERSION_CONTROL_PUSH_MODAL_KEY,
|
||||
SOURCE_CONTROL_PUSH_MODAL_KEY,
|
||||
} from '@/constants';
|
||||
|
||||
import AboutModal from './AboutModal.vue';
|
||||
@@ -171,7 +171,7 @@ import ActivationModal from './ActivationModal.vue';
|
||||
import ImportCurlModal from './ImportCurlModal.vue';
|
||||
import WorkflowShareModal from './WorkflowShareModal.ee.vue';
|
||||
import EventDestinationSettingsModal from '@/components/SettingsLogStreaming/EventDestinationSettingsModal.ee.vue';
|
||||
import VersionControlPushModal from '@/components/VersionControlPushModal.ee.vue';
|
||||
import SourceControlPushModal from '@/components/SourceControlPushModal.ee.vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Modals',
|
||||
@@ -199,7 +199,7 @@ export default defineComponent({
|
||||
WorkflowShareModal,
|
||||
ImportCurlModal,
|
||||
EventDestinationSettingsModal,
|
||||
VersionControlPushModal,
|
||||
SourceControlPushModal,
|
||||
},
|
||||
data: () => ({
|
||||
COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY,
|
||||
@@ -224,7 +224,7 @@ export default defineComponent({
|
||||
WORKFLOW_ACTIVE_MODAL_KEY,
|
||||
IMPORT_CURL_MODAL_KEY,
|
||||
LOG_STREAM_MODAL_KEY,
|
||||
VERSION_CONTROL_PUSH_MODAL_KEY,
|
||||
SOURCE_CONTROL_PUSH_MODAL_KEY,
|
||||
}),
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -83,12 +83,12 @@ export default defineComponent({
|
||||
activateOnRouteNames: [VIEWS.AUDIT_LOGS],
|
||||
},
|
||||
{
|
||||
id: 'settings-version-control',
|
||||
id: 'settings-source-control',
|
||||
icon: 'code-branch',
|
||||
label: this.$locale.baseText('settings.versionControl.title'),
|
||||
label: this.$locale.baseText('settings.sourceControl.title'),
|
||||
position: 'top',
|
||||
available: this.canAccessVersionControl(),
|
||||
activateOnRouteNames: [VIEWS.VERSION_CONTROL],
|
||||
available: this.canAccessSourceControl(),
|
||||
activateOnRouteNames: [VIEWS.SOURCE_CONTROL],
|
||||
},
|
||||
{
|
||||
id: 'settings-sso',
|
||||
@@ -164,8 +164,8 @@ export default defineComponent({
|
||||
canAccessUsageAndPlan(): boolean {
|
||||
return this.canUserAccessRouteByName(VIEWS.USAGE);
|
||||
},
|
||||
canAccessVersionControl(): boolean {
|
||||
return this.canUserAccessRouteByName(VIEWS.VERSION_CONTROL);
|
||||
canAccessSourceControl(): boolean {
|
||||
return this.canUserAccessRouteByName(VIEWS.SOURCE_CONTROL);
|
||||
},
|
||||
canAccessAuditLogs(): boolean {
|
||||
return this.canUserAccessRouteByName(VIEWS.AUDIT_LOGS);
|
||||
@@ -226,9 +226,9 @@ export default defineComponent({
|
||||
void this.$router.push({ name: VIEWS.SSO_SETTINGS });
|
||||
}
|
||||
break;
|
||||
case 'settings-version-control':
|
||||
if (this.$router.currentRoute.name !== VIEWS.VERSION_CONTROL) {
|
||||
void this.$router.push({ name: VIEWS.VERSION_CONTROL });
|
||||
case 'settings-source-control':
|
||||
if (this.$router.currentRoute.name !== VIEWS.SOURCE_CONTROL) {
|
||||
void this.$router.push({ name: VIEWS.SOURCE_CONTROL });
|
||||
}
|
||||
break;
|
||||
case 'settings-audit-logs':
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
<script lang="ts" setup>
|
||||
import Modal from './Modal.vue';
|
||||
import { CREDENTIAL_EDIT_MODAL_KEY, VERSION_CONTROL_PUSH_MODAL_KEY } from '@/constants';
|
||||
import { CREDENTIAL_EDIT_MODAL_KEY, SOURCE_CONTROL_PUSH_MODAL_KEY } from '@/constants';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import type { PropType } from 'vue';
|
||||
import type { EventBus } from 'n8n-design-system/utils';
|
||||
import type { VersionControlAggregatedFile } from '@/Interface';
|
||||
import type { SourceControlAggregatedFile } from '@/Interface';
|
||||
import { useI18n, useLoadingService, useToast } from '@/composables';
|
||||
import { useVersionControlStore } from '@/stores/versionControl.store';
|
||||
import { useSourceControlStore } from '@/stores/sourceControl.store';
|
||||
import { useUIStore } from '@/stores';
|
||||
import { useRoute } from 'vue-router/composables';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object as PropType<{ eventBus: EventBus; status: VersionControlAggregatedFile[] }>,
|
||||
type: Object as PropType<{ eventBus: EventBus; status: SourceControlAggregatedFile[] }>,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
@@ -21,11 +21,11 @@ const loadingService = useLoadingService();
|
||||
const uiStore = useUIStore();
|
||||
const toast = useToast();
|
||||
const { i18n } = useI18n();
|
||||
const versionControlStore = useVersionControlStore();
|
||||
const sourceControlStore = useSourceControlStore();
|
||||
const route = useRoute();
|
||||
|
||||
const staged = ref<Record<string, boolean>>({});
|
||||
const files = ref<VersionControlAggregatedFile[]>(props.data.status || []);
|
||||
const files = ref<SourceControlAggregatedFile[]>(props.data.status || []);
|
||||
|
||||
const commitMessage = ref('');
|
||||
const loading = ref(true);
|
||||
@@ -61,8 +61,8 @@ function getContext() {
|
||||
return '';
|
||||
}
|
||||
|
||||
function getStagedFilesByContext(files: VersionControlAggregatedFile[]): Record<string, boolean> {
|
||||
const stagedFiles: VersionControlAggregatedFile[] = [];
|
||||
function getStagedFilesByContext(files: SourceControlAggregatedFile[]): Record<string, boolean> {
|
||||
const stagedFiles: SourceControlAggregatedFile[] = [];
|
||||
if (context.value === 'workflows') {
|
||||
stagedFiles.push(...files.filter((file) => file.file.startsWith('workflows')));
|
||||
} else if (context.value === 'credentials') {
|
||||
@@ -78,7 +78,7 @@ function getStagedFilesByContext(files: VersionControlAggregatedFile[]): Record<
|
||||
}, {});
|
||||
}
|
||||
|
||||
function setStagedStatus(file: VersionControlAggregatedFile, status: boolean) {
|
||||
function setStagedStatus(file: SourceControlAggregatedFile, status: boolean) {
|
||||
staged.value = {
|
||||
...staged.value,
|
||||
[file.file]: status,
|
||||
@@ -86,24 +86,24 @@ function setStagedStatus(file: VersionControlAggregatedFile, status: boolean) {
|
||||
}
|
||||
|
||||
function close() {
|
||||
uiStore.closeModal(VERSION_CONTROL_PUSH_MODAL_KEY);
|
||||
uiStore.closeModal(SOURCE_CONTROL_PUSH_MODAL_KEY);
|
||||
}
|
||||
|
||||
async function commitAndPush() {
|
||||
const fileNames = files.value.filter((file) => staged.value[file.file]).map((file) => file.file);
|
||||
|
||||
loadingService.startLoading(i18n.baseText('settings.versionControl.loading.push'));
|
||||
loadingService.startLoading(i18n.baseText('settings.sourceControl.loading.push'));
|
||||
close();
|
||||
|
||||
try {
|
||||
await versionControlStore.pushWorkfolder({
|
||||
await sourceControlStore.pushWorkfolder({
|
||||
commitMessage: commitMessage.value,
|
||||
fileNames,
|
||||
});
|
||||
|
||||
toast.showToast({
|
||||
title: i18n.baseText('settings.versionControl.modals.push.success.title'),
|
||||
message: i18n.baseText('settings.versionControl.modals.push.success.description'),
|
||||
title: i18n.baseText('settings.sourceControl.modals.push.success.title'),
|
||||
message: i18n.baseText('settings.sourceControl.modals.push.success.description'),
|
||||
type: 'success',
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -117,27 +117,27 @@ async function commitAndPush() {
|
||||
<template>
|
||||
<Modal
|
||||
width="812px"
|
||||
:title="i18n.baseText('settings.versionControl.modals.push.title')"
|
||||
:title="i18n.baseText('settings.sourceControl.modals.push.title')"
|
||||
:eventBus="data.eventBus"
|
||||
:name="VERSION_CONTROL_PUSH_MODAL_KEY"
|
||||
:name="SOURCE_CONTROL_PUSH_MODAL_KEY"
|
||||
>
|
||||
<template #content>
|
||||
<div :class="$style.container">
|
||||
<n8n-text>
|
||||
{{ i18n.baseText('settings.versionControl.modals.push.description') }}
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.description') }}
|
||||
<span v-if="context">
|
||||
{{ i18n.baseText(`settings.versionControl.modals.push.description.${context}`) }}
|
||||
{{ i18n.baseText(`settings.sourceControl.modals.push.description.${context}`) }}
|
||||
</span>
|
||||
<n8n-link
|
||||
:href="i18n.baseText('settings.versionControl.modals.push.description.learnMore.url')"
|
||||
:href="i18n.baseText('settings.sourceControl.modals.push.description.learnMore.url')"
|
||||
>
|
||||
{{ i18n.baseText('settings.versionControl.modals.push.description.learnMore') }}
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.description.learnMore') }}
|
||||
</n8n-link>
|
||||
</n8n-text>
|
||||
|
||||
<div v-if="files.length > 0">
|
||||
<n8n-text bold tag="p" class="mt-l mb-2xs">
|
||||
{{ i18n.baseText('settings.versionControl.modals.push.filesToCommit') }}
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.filesToCommit') }}
|
||||
</n8n-text>
|
||||
<n8n-card
|
||||
v-for="file in files"
|
||||
@@ -168,19 +168,19 @@ async function commitAndPush() {
|
||||
</n8n-card>
|
||||
|
||||
<n8n-text bold tag="p" class="mt-l mb-2xs">
|
||||
{{ i18n.baseText('settings.versionControl.modals.push.commitMessage') }}
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.commitMessage') }}
|
||||
</n8n-text>
|
||||
<n8n-input
|
||||
type="text"
|
||||
v-model="commitMessage"
|
||||
:placeholder="
|
||||
i18n.baseText('settings.versionControl.modals.push.commitMessage.placeholder')
|
||||
i18n.baseText('settings.sourceControl.modals.push.commitMessage.placeholder')
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="!loading">
|
||||
<n8n-callout class="mt-l">
|
||||
{{ i18n.baseText('settings.versionControl.modals.push.everythingIsUpToDate') }}
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.everythingIsUpToDate') }}
|
||||
</n8n-callout>
|
||||
</div>
|
||||
</div>
|
||||
@@ -189,10 +189,10 @@ async function commitAndPush() {
|
||||
<template #footer>
|
||||
<div :class="$style.footer">
|
||||
<n8n-button type="tertiary" class="mr-2xs" @click="close">
|
||||
{{ i18n.baseText('settings.versionControl.modals.push.buttons.cancel') }}
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.buttons.cancel') }}
|
||||
</n8n-button>
|
||||
<n8n-button type="primary" :disabled="isSubmitDisabled" @click="commitAndPush">
|
||||
{{ i18n.baseText('settings.versionControl.modals.push.buttons.save') }}
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.buttons.save') }}
|
||||
</n8n-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -366,7 +366,7 @@ import {
|
||||
useRootStore,
|
||||
useWorkflowsEEStore,
|
||||
useUsersStore,
|
||||
useVersionControlStore,
|
||||
useSourceControlStore,
|
||||
} from '@/stores';
|
||||
import { createEventBus } from 'n8n-design-system';
|
||||
|
||||
@@ -439,7 +439,7 @@ export default defineComponent({
|
||||
useSettingsStore,
|
||||
useWorkflowsStore,
|
||||
useWorkflowsEEStore,
|
||||
useVersionControlStore,
|
||||
useSourceControlStore,
|
||||
),
|
||||
workflowName(): string {
|
||||
return this.workflowsStore.workflowName;
|
||||
@@ -464,7 +464,7 @@ export default defineComponent({
|
||||
return this.workflowsEEStore.getWorkflowOwnerName(`${this.workflowId}`, fallback);
|
||||
},
|
||||
readOnlyEnv(): boolean {
|
||||
return this.versionControlStore.preferences.branchReadOnly;
|
||||
return this.sourceControlStore.preferences.branchReadOnly;
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
|
||||
@@ -7,16 +7,16 @@ import { merge } from 'lodash-es';
|
||||
import { STORES } from '@/constants';
|
||||
import { i18nInstance } from '@/plugins/i18n';
|
||||
import { SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils';
|
||||
import MainSidebarVersionControl from '@/components/MainSidebarVersionControl.vue';
|
||||
import { useUsersStore, useVersionControlStore } from '@/stores';
|
||||
import MainSidebarSourceControl from '@/components/MainSidebarSourceControl.vue';
|
||||
import { useUsersStore, useSourceControlStore } from '@/stores';
|
||||
|
||||
let pinia: ReturnType<typeof createTestingPinia>;
|
||||
let versionControlStore: ReturnType<typeof useVersionControlStore>;
|
||||
let sourceControlStore: ReturnType<typeof useSourceControlStore>;
|
||||
let usersStore: ReturnType<typeof useUsersStore>;
|
||||
|
||||
const renderComponent = (renderOptions: Parameters<typeof render>[1] = {}) => {
|
||||
return render(
|
||||
MainSidebarVersionControl,
|
||||
MainSidebarSourceControl,
|
||||
{
|
||||
pinia,
|
||||
i18n: i18nInstance,
|
||||
@@ -28,7 +28,7 @@ const renderComponent = (renderOptions: Parameters<typeof render>[1] = {}) => {
|
||||
);
|
||||
};
|
||||
|
||||
describe('MainSidebarVersionControl', () => {
|
||||
describe('MainSidebarSourceControl', () => {
|
||||
const getItemSpy = vi.spyOn(Storage.prototype, 'getItem');
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -41,7 +41,7 @@ describe('MainSidebarVersionControl', () => {
|
||||
},
|
||||
});
|
||||
|
||||
versionControlStore = useVersionControlStore();
|
||||
sourceControlStore = useSourceControlStore();
|
||||
usersStore = useUsersStore();
|
||||
});
|
||||
|
||||
@@ -53,22 +53,13 @@ describe('MainSidebarVersionControl', () => {
|
||||
|
||||
it('should render empty content', async () => {
|
||||
const { getByTestId } = renderComponent({ props: { isCollapsed: false } });
|
||||
expect(getByTestId('main-sidebar-version-control')).toBeInTheDocument();
|
||||
expect(getByTestId('main-sidebar-version-control')).toBeEmptyDOMElement();
|
||||
});
|
||||
|
||||
it('should render setup content', async () => {
|
||||
vi.spyOn(versionControlStore, 'isEnterpriseVersionControlEnabled', 'get').mockReturnValue(true);
|
||||
vi.spyOn(usersStore, 'isInstanceOwner', 'get').mockReturnValue(true);
|
||||
|
||||
const { getByTestId, queryByTestId } = renderComponent({ props: { isCollapsed: false } });
|
||||
expect(getByTestId('main-sidebar-version-control-setup')).toBeInTheDocument();
|
||||
expect(queryByTestId('main-sidebar-version-control-connected')).not.toBeInTheDocument();
|
||||
expect(getByTestId('main-sidebar-source-control')).toBeInTheDocument();
|
||||
expect(getByTestId('main-sidebar-source-control')).toBeEmptyDOMElement();
|
||||
});
|
||||
|
||||
describe('when connected', () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(versionControlStore, 'preferences', 'get').mockReturnValue({
|
||||
vi.spyOn(sourceControlStore, 'preferences', 'get').mockReturnValue({
|
||||
branchName: 'main',
|
||||
branches: [],
|
||||
authorName: '',
|
||||
@@ -83,12 +74,12 @@ describe('MainSidebarVersionControl', () => {
|
||||
|
||||
it('should render the appropriate content', async () => {
|
||||
const { getByTestId, queryByTestId } = renderComponent({ props: { isCollapsed: false } });
|
||||
expect(getByTestId('main-sidebar-version-control-connected')).toBeInTheDocument();
|
||||
expect(queryByTestId('main-sidebar-version-control-setup')).not.toBeInTheDocument();
|
||||
expect(getByTestId('main-sidebar-source-control-connected')).toBeInTheDocument();
|
||||
expect(queryByTestId('main-sidebar-source-control-setup')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show toast error if pull response http status code is not 409', async () => {
|
||||
vi.spyOn(versionControlStore, 'pullWorkfolder').mockRejectedValueOnce({
|
||||
vi.spyOn(sourceControlStore, 'pullWorkfolder').mockRejectedValueOnce({
|
||||
response: { status: 400 },
|
||||
});
|
||||
const { getAllByRole, getByRole } = renderComponent({ props: { isCollapsed: false } });
|
||||
@@ -98,7 +89,7 @@ describe('MainSidebarVersionControl', () => {
|
||||
});
|
||||
|
||||
it('should show confirm if pull response http status code is 409', async () => {
|
||||
vi.spyOn(versionControlStore, 'pullWorkfolder').mockRejectedValueOnce({
|
||||
vi.spyOn(sourceControlStore, 'pullWorkfolder').mockRejectedValueOnce({
|
||||
response: { status: 409 },
|
||||
});
|
||||
const { getAllByRole, getByRole } = renderComponent({ props: { isCollapsed: false } });
|
||||
Reference in New Issue
Block a user