mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-19 02:51:14 +00:00
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
254
packages/editor-ui/src/components/SourceControlPushModal.ee.vue
Normal file
254
packages/editor-ui/src/components/SourceControlPushModal.ee.vue
Normal file
@@ -0,0 +1,254 @@
|
||||
<script lang="ts" setup>
|
||||
import Modal from './Modal.vue';
|
||||
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 { SourceControlAggregatedFile } from '@/Interface';
|
||||
import { useI18n, useLoadingService, useToast } from '@/composables';
|
||||
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: SourceControlAggregatedFile[] }>,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
const loadingService = useLoadingService();
|
||||
const uiStore = useUIStore();
|
||||
const toast = useToast();
|
||||
const { i18n } = useI18n();
|
||||
const sourceControlStore = useSourceControlStore();
|
||||
const route = useRoute();
|
||||
|
||||
const staged = ref<Record<string, boolean>>({});
|
||||
const files = ref<SourceControlAggregatedFile[]>(props.data.status || []);
|
||||
|
||||
const commitMessage = ref('');
|
||||
const loading = ref(true);
|
||||
const context = ref<'workflow' | 'workflows' | 'credentials' | string>('');
|
||||
|
||||
const isSubmitDisabled = computed(() => {
|
||||
return !commitMessage.value || Object.values(staged.value).every((value) => !value);
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
context.value = getContext();
|
||||
try {
|
||||
staged.value = getStagedFilesByContext(files.value);
|
||||
} catch (error) {
|
||||
toast.showError(error, i18n.baseText('error'));
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
function getContext() {
|
||||
if (route.fullPath.startsWith('/workflows')) {
|
||||
return 'workflows';
|
||||
} else if (
|
||||
route.fullPath.startsWith('/credentials') ||
|
||||
uiStore.modals[CREDENTIAL_EDIT_MODAL_KEY].open
|
||||
) {
|
||||
return 'credentials';
|
||||
} else if (route.fullPath.startsWith('/workflow/')) {
|
||||
return 'workflow';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
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') {
|
||||
stagedFiles.push(...files.filter((file) => file.file.startsWith('credentials')));
|
||||
} else if (context.value === 'workflow') {
|
||||
const workflowId = route.params.name as string;
|
||||
stagedFiles.push(...files.filter((file) => file.type === 'workflow' && file.id === workflowId));
|
||||
}
|
||||
|
||||
return stagedFiles.reduce<Record<string, boolean>>((acc, file) => {
|
||||
acc[file.file] = true;
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
function setStagedStatus(file: SourceControlAggregatedFile, status: boolean) {
|
||||
staged.value = {
|
||||
...staged.value,
|
||||
[file.file]: status,
|
||||
};
|
||||
}
|
||||
|
||||
function close() {
|
||||
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.sourceControl.loading.push'));
|
||||
close();
|
||||
|
||||
try {
|
||||
await sourceControlStore.pushWorkfolder({
|
||||
commitMessage: commitMessage.value,
|
||||
fileNames,
|
||||
});
|
||||
|
||||
toast.showToast({
|
||||
title: i18n.baseText('settings.sourceControl.modals.push.success.title'),
|
||||
message: i18n.baseText('settings.sourceControl.modals.push.success.description'),
|
||||
type: 'success',
|
||||
});
|
||||
} catch (error) {
|
||||
toast.showError(error, i18n.baseText('error'));
|
||||
} finally {
|
||||
loadingService.stopLoading();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal
|
||||
width="812px"
|
||||
:title="i18n.baseText('settings.sourceControl.modals.push.title')"
|
||||
:eventBus="data.eventBus"
|
||||
:name="SOURCE_CONTROL_PUSH_MODAL_KEY"
|
||||
>
|
||||
<template #content>
|
||||
<div :class="$style.container">
|
||||
<n8n-text>
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.description') }}
|
||||
<span v-if="context">
|
||||
{{ i18n.baseText(`settings.sourceControl.modals.push.description.${context}`) }}
|
||||
</span>
|
||||
<n8n-link
|
||||
:href="i18n.baseText('settings.sourceControl.modals.push.description.learnMore.url')"
|
||||
>
|
||||
{{ 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.sourceControl.modals.push.filesToCommit') }}
|
||||
</n8n-text>
|
||||
<n8n-card
|
||||
v-for="file in files"
|
||||
:key="file.file"
|
||||
:class="$style.listItem"
|
||||
@click="setStagedStatus(file, !staged[file.file])"
|
||||
>
|
||||
<div :class="$style.listItemBody">
|
||||
<n8n-checkbox
|
||||
:value="staged[file.file]"
|
||||
:class="$style.listItemCheckbox"
|
||||
@input="setStagedStatus(file, !staged[file.file])"
|
||||
/>
|
||||
<n8n-text bold>
|
||||
<span v-if="file.status === 'deleted'">
|
||||
<span v-if="file.type === 'workflow'"> Workflow </span>
|
||||
<span v-if="file.type === 'credential'"> Credential </span>
|
||||
Id: {{ file.id }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ file.name }}
|
||||
</span>
|
||||
</n8n-text>
|
||||
<n8n-badge :class="$style.listItemStatus">
|
||||
{{ file.status }}
|
||||
</n8n-badge>
|
||||
</div>
|
||||
</n8n-card>
|
||||
|
||||
<n8n-text bold tag="p" class="mt-l mb-2xs">
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.commitMessage') }}
|
||||
</n8n-text>
|
||||
<n8n-input
|
||||
type="text"
|
||||
v-model="commitMessage"
|
||||
:placeholder="
|
||||
i18n.baseText('settings.sourceControl.modals.push.commitMessage.placeholder')
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="!loading">
|
||||
<n8n-callout class="mt-l">
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.everythingIsUpToDate') }}
|
||||
</n8n-callout>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<div :class="$style.footer">
|
||||
<n8n-button type="tertiary" class="mr-2xs" @click="close">
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.buttons.cancel') }}
|
||||
</n8n-button>
|
||||
<n8n-button type="primary" :disabled="isSubmitDisabled" @click="commitAndPush">
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.buttons.save') }}
|
||||
</n8n-button>
|
||||
</div>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style module lang="scss">
|
||||
.container > * {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.actionButtons {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
margin-top: var(--spacing-2xs);
|
||||
margin-bottom: var(--spacing-2xs);
|
||||
cursor: pointer;
|
||||
transition: border 0.3s ease;
|
||||
padding: var(--spacing-xs);
|
||||
|
||||
&:hover {
|
||||
border-color: var(--color-foreground-dark);
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.listItemBody {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.listItemCheckbox {
|
||||
display: inline-flex !important;
|
||||
margin-bottom: 0 !important;
|
||||
margin-right: var(--spacing-2xs);
|
||||
}
|
||||
|
||||
.listItemStatus {
|
||||
margin-left: var(--spacing-2xs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user