Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(editor): Ask AI #6672

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
32eb324
feat(editor): Ask AI tab and CLi connection
OlegIvaniv Jul 17, 2023
c932c91
Merge branch 'ask-ai-code' into ado-610-fe-ai-powered-code-generation…
OlegIvaniv Jul 17, 2023
fca2b52
Remove old getSchema util method
OlegIvaniv Jul 17, 2023
f1c3b8a
Increase CSS specificity of the CodeNodeEditor global overrides
OlegIvaniv Jul 17, 2023
c8d84ba
feat(editor): Magic Connect
OlegIvaniv Jul 18, 2023
d01439a
Improve AI controller, load conditionally, UX modal imporvements
OlegIvaniv Jul 25, 2023
0e39fee
Extract-out AI curl
OlegIvaniv Jul 25, 2023
88628a7
Move loading phrases to locale, add support for ask ai experiment
OlegIvaniv Jul 26, 2023
6215d97
fix build
OlegIvaniv Jul 26, 2023
96bd0d4
adjust communication
RicardoE105 Aug 1, 2023
3341217
fix: Remove duplicate source control preferences fetching (no-changel…
alexgrozav Jul 17, 2023
535dc97
fix(Slack Node): Add UTM params to n8n reference in Slack message (no…
OlegIvaniv Jul 17, 2023
67752a6
fix(FileMaker Node): Improve returned error responses (#6585)
airmoi Jul 17, 2023
2a75136
fix(Microsoft Outlook Node): Fix issue with category not correctly ap…
Joffcom Jul 17, 2023
7e21d6c
feat(Airtable Node): Overhaul (#6200)
michael-radency Jul 17, 2023
949937d
fix(core): Deleting manual executions should defer deleting binary da…
netroy Jul 18, 2023
64b48a2
fix(editor): Add paywall state to non owner users for Variables (#6679)
cstuncsik Jul 18, 2023
551b9a8
refactor(core): Refactor WorkflowStatistics code (no-changelog) (#6617)
netroy Jul 18, 2023
3a672b9
fix(editor): Hide Execute Node button for unknown nodes (#6684)
ivov Jul 18, 2023
e0cc835
feat: Allow hiding credential params on cloud (#6687)
ivov Jul 18, 2023
cfc25ec
fix: Stop n8n from complaining about credentials when saving a new wo…
krynble Jul 18, 2023
89998ff
fix(core): Upgrade semver to address CVE-2022-25883 (#6689)
netroy Jul 18, 2023
d8eac09
ci: Fix test checker glob (no changelog) (#6682)
ivov Jul 18, 2023
8a67978
fix(API): Do not add starting node on workflow creation (#6686)
ivov Jul 18, 2023
34e1a1b
fix(core): Filter out workflows that failed to activate on startup (#…
ivov Jul 18, 2023
dc889ce
fix(core): Load SAML libraries dynamically (#6690)
flipswitchingmonkey Jul 18, 2023
bb63027
fix(crowd.dev Node): Fix documentation urls for crowd.dev credentials…
netroy Jul 18, 2023
cecaac2
feat(Read PDF Node): Replace pdf-parse with pdfjs, and add support fo…
netroy Jul 18, 2023
23ac8b5
feat: Allow `eslint-config` to be externally consumable (#6694)
ivov Jul 19, 2023
7763aed
fix(Contentful Node): Fix typo in credential name (no-changelog) (#6692)
Joffcom Jul 19, 2023
e1adaa5
fix(editor): Ensure default credential values are not detected as dir…
ivov Jul 19, 2023
9fff0ee
feat(Google Cloud Storage Node): Use streaming for file uploads (#6462)
netroy Jul 19, 2023
e3e9e8a
fix(editor): Prevent RMC from loading schema if it's already cached (…
MiloradFilipovic Jul 19, 2023
655e55f
fix(API): Fix issue with workflow setting not supporting newer nanoid…
Joffcom Jul 19, 2023
80ae275
ci: Fix test workflows (no-changelog) (#6698)
netroy Jul 19, 2023
407b4fb
fix(core): Banner dismissal should also work for users migrating to v…
netroy Jul 19, 2023
1f03bfd
fix(Postgres Node): For select queries, empty result should be be rep…
netroy Jul 19, 2023
d94101f
feat(editor): Removing `ph-no-capture` class from some elements (#6674)
MiloradFilipovic Jul 19, 2023
69c0f2f
fix(editor): Remove global link styling in v1 banner (#6705)
MiloradFilipovic Jul 20, 2023
5a6d48f
fix: Add missing indices on sqlite (#6673)
valya Jul 20, 2023
351184b
test: Move test timeout to `/cli` (no-changelog) (#6712)
ivov Jul 20, 2023
835588c
fix(core): Redirect user to previous url after SSO signin (#6710)
flipswitchingmonkey Jul 20, 2023
acb8cb0
fix(FTP Node): List recursive ignore . and .. to prevent infinite loo…
maspio Jul 21, 2023
77a7d76
ci: Fix running e2e tests in dev mode (no-changelog) (#6717)
netroy Jul 21, 2023
5196f37
fix(Google BigQuery Node): Error description improvement (#6715)
michael-radency Jul 21, 2023
c6f7bb2
fix(GitLab Trigger Node): Fix trigger activation 404 error (#6711)
maspio Jul 21, 2023
8fa9263
fix(core): Support redis cluster in queue mode (#6708)
flipswitchingmonkey Jul 21, 2023
a4d3eaf
fix(editor): Skip error line highlighting if out of range (#6721)
ivov Jul 24, 2023
64ea002
fix(AwsS3 Node): Fix issue if bucket name contains a '.' (#6542)
Jordan-Hall Jul 24, 2023
f68a779
test(editor): Add canvas actions E2E tests (#6723)
cstuncsik Jul 24, 2023
88e54e6
feat(Rundeck Node): Add support for node filters (#5633)
qg-horie Jul 24, 2023
cddd47e
fix(Gmail Trigger Node): Early returns in case of no data (#6727)
michael-radency Jul 24, 2023
4e09ae1
fix(core): Use JWT as reset password token (#6714)
RicardoE105 Jul 24, 2023
77f00e1
ci: Fix tests on postgres (no-changelog)
netroy Jul 24, 2023
e1120cb
refactor(core): Prevent community packages queries if feature is disa…
ivov Jul 25, 2023
1198d8b
feat(core): Add cache service (#6729)
flipswitchingmonkey Jul 25, 2023
c2d00b4
Revert "test(editor): Add canvas actions E2E tests" (#6736)
OlegIvaniv Jul 25, 2023
788322b
fix(Postgres Node): Arrays in query replacement fix (#6718)
michael-radency Jul 25, 2023
5ae1b73
fix(Telegram Trigger Node): Add guard to 'include' call on null or un…
michael-radency Jul 25, 2023
a5f7d51
fix(core): Use `exec` in docker images to forward signals correctly (…
guoard Jul 25, 2023
4509bc0
refactor(core): Move webhook DB access to repository (no-changelog) (…
ivov Jul 25, 2023
c065ba0
feat: Environments release using source control (#6653)
flipswitchingmonkey Jul 26, 2023
6b6c3ab
fix(core): Fix RemoveResetPasswordColumns migration for sqlite (no-ch…
netroy Jul 26, 2023
62df48e
ci: Update changelog generation to work with node 18
netroy Jul 26, 2023
1f05322
refactor: Remove webhook from `IDatabaseCollections` (no-changelog) (…
ivov Jul 26, 2023
60444dd
:rocket: Release 1.1.0 (#6746)
github-actions[bot] Jul 26, 2023
32c7412
fix(Lemlist Node): Fix pagination issues with campaigns and activitie…
Joffcom Jul 26, 2023
29c7895
ci: Fix linting issues (no-changelog) (#6747)
netroy Jul 26, 2023
4b0e241
fix(core): Allow ignoring SSL issues on generic oauth2 credentials (#…
netroy Jul 26, 2023
58ab95b
refactor: Remove all references to the resetPasswordToken field (no-c…
netroy Jul 27, 2023
a67e3d8
refactor(core): Use mixins to delete redundant code between Entity cl…
netroy Jul 27, 2023
5132de3
fix: Display source control buttons properly (#6756)
krynble Jul 27, 2023
d01fc0c
feat(editor): Migrate Design System and Editor UI to Vue 3 (#6476)
alexgrozav Jul 28, 2023
1b0d270
perf(editor): Memoize locale translate calls during actions generatio…
OlegIvaniv Jul 28, 2023
c25a4a2
fix(editor): Close tags dropdown when modal is opened (#6766)
MiloradFilipovic Jul 28, 2023
8d88810
fix: Show NodeIcon tooltips by removing pointer-events: none (#6777)
alexgrozav Jul 28, 2023
bbaa3fb
fix: Respect set modal widths (#6771)
mutdmour Jul 28, 2023
c3f65d5
fix(editor): Fix tooltip opening delay prop name (#6776)
alexgrozav Jul 28, 2023
2e2b8c8
fix(editor): Fix collapsed sub menu elements (#6778)
cstuncsik Jul 28, 2023
1bb7616
fix: Remove number input arrows (no-changelog) (#6782)
alexgrozav Jul 28, 2023
2b01039
ci: Update most of the dev tooling (no-changelog) (#6780)
netroy Jul 28, 2023
ee8e7d4
fix(TheHive Node): Treat `ApiKey` as a secret (#6786)
netroy Jul 28, 2023
5140bcd
test(editor): Prevent node view unload by default in e2e run (#6787)
OlegIvaniv Jul 28, 2023
5b81126
fix(editor): Resolve vue 3 related console-warnings (#6779)
OlegIvaniv Jul 28, 2023
bf2262c
fix(editor): Vue3 - Fix modal positioning and multi-select tag sizing…
MiloradFilipovic Jul 28, 2023
c5e3c54
ci: Fix linting issues (no-changelog) (#6788)
netroy Jul 28, 2023
48c914f
fix(editor): Fix code node highlight error (#6791)
OlegIvaniv Jul 28, 2023
707d5a2
feat(core): Credentials for popular SecOps services, Part 1 (#6775)
michael-radency Jul 31, 2023
fadb10a
refactor: Clear unused ESLint directives from BE packages (no-changel…
ivov Jul 31, 2023
9cf6c25
refactor(core): Cache workflow ownership (#6738)
ivov Jul 31, 2023
5308f31
fix(editor): Prevent text edit dialog from re-opening in same tick (#…
alexgrozav Jul 31, 2023
85484da
test(editor): Do not chain invoke calls after assertions in 24-ndv-pa…
OlegIvaniv Jul 31, 2023
ea95e06
fix(Todoist Node): Fix issue with section id being ignored (#6799)
Joffcom Jul 31, 2023
df32517
test(editor): Add canvas actions E2E tests (#6723) (#6790)
cstuncsik Jul 31, 2023
a9a2c9e
fix(core): Add missing primary key on the `execution_data` table on p…
netroy Jul 31, 2023
a16b8fc
fix: Review fixes
OlegIvaniv Aug 3, 2023
88b4a08
fix: Fin locales
OlegIvaniv Aug 3, 2023
3fc6ce8
Merge branch 'master' into ado-610-fe-ai-powered-code-generation-in-t…
OlegIvaniv Aug 7, 2023
1ea7e46
Fix merging errors
OlegIvaniv Aug 7, 2023
e18ae98
Map erros based on statusCode
OlegIvaniv Aug 7, 2023
4fe3fab
Fix code replacing
OlegIvaniv Aug 7, 2023
e8d6cfd
Fix code formatting
OlegIvaniv Aug 7, 2023
8ca6ba4
Address review points
OlegIvaniv Aug 8, 2023
af1b403
Optionally access total_tokens
OlegIvaniv Aug 8, 2023
d480095
Clean-up Ask AI modal
OlegIvaniv Aug 9, 2023
f7b30ee
Store prompt in sessionStorage
OlegIvaniv Aug 9, 2023
c728b33
Improve schema generation, only get parent nodes
OlegIvaniv Aug 9, 2023
0f9ae7b
Send error messages to telemetry, aske before switching tabs
OlegIvaniv Aug 10, 2023
ad8477d
Add locale
OlegIvaniv Aug 10, 2023
7c60c87
Merge branch 'master' into ado-610-fe-ai-powered-code-generation-in-t…
OlegIvaniv Aug 14, 2023
2bce33e
Post-merge cleanup
OlegIvaniv Aug 14, 2023
c7b7cc9
Move Ask AI into separate folder
OlegIvaniv Aug 14, 2023
7b021b5
Lint fix
OlegIvaniv Aug 14, 2023
24d2cf3
Constants lint fix
OlegIvaniv Aug 14, 2023
4531622
Add Ask AI e2e tests and fix linting issues
OlegIvaniv Aug 15, 2023
b50a92d
Move CircleLoader to design-lib
OlegIvaniv Aug 15, 2023
6adc5d9
Replace circle-lodaer and move el-tabs styles to n8n theme
OlegIvaniv Aug 15, 2023
59fdf98
Fix placeholder & e2e tests
OlegIvaniv Aug 15, 2023
ad573da
Merge branch 'master' into ado-610-fe-ai-powered-code-generation-in-t…
OlegIvaniv Aug 15, 2023
0170368
Remove old CircleLoader
OlegIvaniv Aug 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 29 additions & 34 deletions cypress/e2e/6-code-node.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,43 @@ const WorkflowPage = new WorkflowPageClass();
const ndv = new NDV();

describe('Code node', () => {
beforeEach(() => {
WorkflowPage.actions.visit();
});

it('should execute the placeholder in all-items mode successfully', () => {
WorkflowPage.actions.addInitialNodeToCanvas('Manual');
WorkflowPage.actions.addNodeToCanvas('Code');
WorkflowPage.actions.openNode('Code');
describe('Code editor', () => {
beforeEach(() => {
WorkflowPage.actions.visit();
WorkflowPage.actions.addInitialNodeToCanvas('Manual');
WorkflowPage.actions.addNodeToCanvas('Code', true, true);
});

ndv.actions.execute();
it('should show correct placeholders switching modes', () => {
cy.contains("// Loop over input items and add a new field").should('be.visible');

WorkflowPage.getters.successToast().contains('Node executed successfully');
});
ndv.getters.parameterInput('mode').click();
ndv.actions.selectOptionInParameterDropdown('mode', 'Run Once for Each Item');

it('should execute the placeholder in each-item mode successfully', () => {
WorkflowPage.actions.addInitialNodeToCanvas('Manual');
WorkflowPage.actions.addNodeToCanvas('Code');
WorkflowPage.actions.openNode('Code');
ndv.getters.parameterInput('mode').click();
ndv.actions.selectOptionInParameterDropdown('mode', 'Run Once for Each Item');
cy.contains("// Add a new field called 'myNewField'").should('be.visible');

ndv.actions.execute();
ndv.getters.parameterInput('mode').click();
ndv.actions.selectOptionInParameterDropdown('mode', 'Run Once for All Items');
cy.contains("// Loop over input items and add a new field").should('be.visible');
})

WorkflowPage.getters.successToast().contains('Node executed successfully');
});
it('should execute the placeholder successfully in both modes', () => {
ndv.actions.execute();

it('should execute the placeholder in each-item mode successfully', () => {
WorkflowPage.actions.addInitialNodeToCanvas('Manual');
WorkflowPage.actions.addNodeToCanvas('Code');
WorkflowPage.actions.openNode('Code');
ndv.getters.parameterInput('mode').click();
ndv.actions.selectOptionInParameterDropdown('mode', 'Run Once for Each Item');
WorkflowPage.getters.successToast().contains('Node executed successfully');
ndv.getters.parameterInput('mode').click();
ndv.actions.selectOptionInParameterDropdown('mode', 'Run Once for Each Item');

ndv.actions.execute();
ndv.actions.execute();

WorkflowPage.getters.successToast().contains('Node executed successfully');
});
WorkflowPage.getters.successToast().contains('Node executed successfully');
});
})

describe('Ask AI', () => {
it('tab should not exist if control or no feature flag', () => {
it('tab should display based on experiment', () => {
WorkflowPage.actions.visit();
cy.window().then((win) => {
// cy.clearAllLocalStorage();
win.featureFlags.override('011_ask_AI', 'control');
WorkflowPage.actions.addInitialNodeToCanvas('Manual');
WorkflowPage.actions.addNodeToCanvas('Code');
Expand All @@ -63,15 +58,15 @@ describe('Code node', () => {

describe('Enabled', () => {
beforeEach(() => {
WorkflowPage.actions.visit();
cy.window().then((win) => {
win.featureFlags.override('011_ask_AI', 'gpt3');
WorkflowPage.actions.addInitialNodeToCanvas('Manual');
WorkflowPage.actions.addNodeToCanvas('Code');
WorkflowPage.actions.openNode('Code');
WorkflowPage.actions.addNodeToCanvas('Code', true, true);
})
})

it('tab should exist if model selected and be selectable', () => {
it('tab should exist if experiment selected and be selectable', () => {
cy.getByTestId('code-node-tab-ai').should('exist');
cy.get('#tab-ask-ai').click();
cy.contains('Hey AI, generate JavaScript').should('exist');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import N8nCircleLoader from './CircleLoader.vue';
import type { StoryFn } from '@storybook/vue3';

export default {
title: 'Atoms/CircleLoader',
component: N8nCircleLoader,
argTypes: {
radius: {
control: {
type: 'number',
},
},
progress: {
control: {
type: 'number',
},
},
strokeWidth: {
control: {
type: 'number',
},
},
},
};

interface Args {
radius: number;
progress: number;
strokeWidth: number;
}

const template: StoryFn<Args> = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nCircleLoader,
},
template: `
<div>
<n8n-circle-loader v-bind="args" />
</div>
`,
});

export const defaultCircleLoader = template.bind({});
defaultCircleLoader.args = {
radius: 20,
progress: 42,
strokeWidth: 10,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { render } from '@testing-library/vue';
import N8NCircleLoader from '../CircleLoader.vue';

describe('N8NCircleLoader', () => {
it('should render correctly', () => {
const wrapper = render(N8NCircleLoader, {
props: {
radius: 20,
progress: 42,
strokeWidth: 10,
},
});
expect(wrapper.html()).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`N8NCircleLoader > should render correctly 1`] = `
"<div class=\\"progress-circle\\"><svg class=\\"progress-ring\\" width=\\"60\\" height=\\"60\\">
<circle class=\\"progressRingCircle\\" stroke-width=\\"10\\" stroke=\\"#DCDFE6\\" fill=\\"transparent\\" r=\\"20\\" cx=\\"30\\" cy=\\"30\\"></circle>
<circle class=\\"progressRingCircle\\" stroke=\\"#5C4EC2\\" stroke-width=\\"10\\" fill=\\"transparent\\" r=\\"20\\" cx=\\"30\\" cy=\\"30\\" style=\\"stroke-dasharray: 125.66370614359172; stroke-dashoffset: 72.8849495632832;\\"></circle>
</svg></div>"
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import N8nCircleLoader from './CircleLoader.vue';

export default N8nCircleLoader;
1 change: 1 addition & 0 deletions packages/design-system/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { default as N8nButton } from './N8nButton';
export { default as N8nCallout } from './N8nCallout';
export { default as N8nCard } from './N8nCard';
export { default as N8nCheckbox } from './N8nCheckbox';
export { default as N8nCircleLoader } from './N8nCircleLoader';
export { default as N8nColorPicker } from './N8nColorPicker';
export { default as N8nDatatable } from './N8nDatatable';
export { default as N8nFormBox } from './N8nFormBox';
Expand Down
2 changes: 2 additions & 0 deletions packages/design-system/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
N8nCallout,
N8nCard,
N8nCheckbox,
N8nCircleLoader,
N8nColorPicker,
N8nDatatable,
N8nFormBox,
Expand Down Expand Up @@ -66,6 +67,7 @@ export const N8nPlugin: Plugin<{}> = {
app.component('n8n-callout', N8nCallout);
app.component('n8n-card', N8nCard);
app.component('n8n-checkbox', N8nCheckbox);
app.component('n8n-circle-loader', N8nCircleLoader);
app.component('n8n-color-picker', N8nColorPicker);
app.component('n8n-datatable', N8nDatatable);
app.component('n8n-form-box', N8nFormBox);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
ASK_AI_MIN_PROMPT_LENGTH,
ASK_AI_LOADING_DURATION_MS,
} from '@/constants';
import CircleLoader from './CircleLoader.vue';

const emit = defineEmits<{
(e: 'submit', code: string): void;
Expand Down Expand Up @@ -150,6 +149,7 @@ async function onSubmit() {
}

startLoading();

try {
const version = useRootStore().versionCli;
const model =
Expand Down Expand Up @@ -273,7 +273,7 @@ onMounted(() => {
<transition name="text-fade-in-out" mode="out-in">
<div v-text="loadingString" :key="loadingPhraseIndex" />
</transition>
<CircleLoader :radius="8" :progress="loaderProgress" :stroke-width="3" />
<n8n-circle-loader :radius="8" :progress="loaderProgress" :stroke-width="3" />
</div>
<n8n-tooltip :disabled="isSubmitEnabled" v-else>
<div>
Expand Down
60 changes: 19 additions & 41 deletions packages/editor-ui/src/components/CodeNodeEditor/CodeNodeEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
@replaceCode="onReplaceCode"
:has-changes="hasChanges"
:key="activeTab"
@started-loading="isLoading = true"
@finished-loading="isLoading = false"
@started-loading="isLoadingAIResponse = true"
@finished-loading="isLoadingAIResponse = false"
/>
</el-tab-pane>
</el-tabs>
Expand Down Expand Up @@ -112,7 +112,7 @@ export default defineComponent({
tabs: ['code', 'ask-ai'],
activeTab: 'code',
hasChanges: false,
isLoading: false,
isLoadingAIResponse: false,
};
},
watch: {
Expand Down Expand Up @@ -150,20 +150,13 @@ export default defineComponent({
},
computed: {
...mapStores(useRootStore, usePostHog),
content(): string {
if (!this.editor) return '';

return this.editor.state.doc.toString();
},
aiEnabled(): boolean {
// AI is enabled only via Posthog experiment. So if user doesn't have feature flag
// we fallback to control which is no-show variant
const isAiExperimentDisabled =
(this.posthogStore.getVariant(ASK_AI_EXPERIMENT.name) ?? ASK_AI_EXPERIMENT.control) ===
ASK_AI_EXPERIMENT.control;
const isAiExperimentEnabled = [ASK_AI_EXPERIMENT.gpt3, ASK_AI_EXPERIMENT.gpt4].includes(
(this.posthogStore.getVariant(ASK_AI_EXPERIMENT.name) ?? '') as string,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is as string needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, because getVariant return types are boolean | string | undefined
CleanShot 2023-08-16 at 11 18 31

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally we would avoid type casting..

);

return (
!isAiExperimentDisabled &&
isAiExperimentEnabled &&
this.settingsStore.settings.ai.enabled &&
this.language === 'javaScript'
);
Expand All @@ -184,9 +177,12 @@ export default defineComponent({
},
},
methods: {
getCurrentEditorContent() {
return this.editor?.state.doc.toString() ?? '';
},
async onBeforeTabLeave(_activeName: string, oldActiveName: string) {
// Confirm dialog if leaving ask-ai tab during loading
if (oldActiveName === 'ask-ai' && this.isLoading) {
if (oldActiveName === 'ask-ai' && this.isLoadingAIResponse) {
const confirmModal = await this.alert(
this.$locale.baseText('codeNodeEditor.askAi.sureLeaveTab'),
{
Expand All @@ -213,7 +209,7 @@ export default defineComponent({
});

this.editor?.dispatch({
changes: { from: 0, to: (this.modelValue || '').length, insert: formattedCode },
changes: { from: 0, to: this.getCurrentEditorContent().length, insert: formattedCode },
});

this.activeTab = 'code';
Expand Down Expand Up @@ -364,40 +360,22 @@ export default defineComponent({

// empty on first load, default param value
if (!this.modelValue) {
this.refreshPlaceholder();
this.$emit('update:modelValue', this.placeholder);
OlegIvaniv marked this conversation as resolved.
Show resolved Hide resolved
}
},
});
</script>

<style lang="scss" module>
:global(.el-tabs) {
:global(.el-tabs__content) {
border: 1px solid var(--color-foreground-base);
border-radius: 0px var(--border-radius-base) var(--border-radius-base);
}
:global(.el-tabs__header) {
border-bottom: 0 !important;
}
:global(.el-tabs__nav) {
padding: 0;
}
:global(.el-tabs__item) {
padding: var(--spacing-5xs) var(--spacing-2xs) !important;
height: auto;
line-height: var(--font-line-height-xloose);
font-weight: var(--font-weight-regular);
font-size: var(--font-size-2xs);

&:not([aria-selected='true']) {
background-color: var(--color-background-base);
border-bottom: 1px solid var(--color-foreground-base) !important;
}
}
:global(.code-editor-tabs .cm-editor) {
<style scoped lang="scss">
:deep(.el-tabs) {
.code-editor-tabs .cm-editor {
border: 0;
}
}
</style>

<style lang="scss" module>
.code-node-editor-container {
position: relative;

Expand Down
9 changes: 1 addition & 8 deletions packages/editor-ui/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -523,21 +523,14 @@ export const KEEP_AUTH_IN_NDV_FOR_NODES = [
export const MAIN_AUTH_FIELD_NAME = 'authentication';
export const NODE_RESOURCE_FIELD_NAME = 'resource';

export const TEMPLATES_EXPERIMENT = {
name: '008_template_variants',
control: 'control',
variant: 'variant',
variantIds: ['1932', '1930', '1931', '1933', '1750', '1748', '1435'],
};

export const ASK_AI_EXPERIMENT = {
name: '011_ask_AI',
control: 'control',
gpt3: 'gpt3',
gpt4: 'gpt4',
};

export const EXPERIMENTS_TO_TRACK = [TEMPLATES_EXPERIMENT.name, ASK_AI_EXPERIMENT.name];
export const EXPERIMENTS_TO_TRACK = [ASK_AI_EXPERIMENT.name];

export const NODE_TYPES_EXCLUDED_FROM_OUTPUT_NAME_APPEND = [FILTER_NODE_TYPE];

Expand Down
24 changes: 24 additions & 0 deletions packages/editor-ui/src/n8n-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,30 @@
font-weight: bold;
}

.el-tabs__content {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant tabs.scss before.. since our theme lives there.. but this is fine for now

border: 1px solid var(--color-foreground-base);
border-radius: 0px var(--border-radius-base) var(--border-radius-base);
}
.el-tabs__header {
border-bottom: 0 !important;
}
.el-tabs__nav {
padding: 0;
overflow: hidden;
}
.el-tabs__item {
padding: var(--spacing-5xs) var(--spacing-2xs) !important;
height: auto;
line-height: var(--font-line-height-xloose);
font-weight: var(--font-weight-regular);
font-size: var(--font-size-2xs);

&:not([aria-selected='true']) {
background-color: var(--color-background-base);
border-bottom: 1px solid var(--color-foreground-base) !important;
}
}

// Loading Indicator
.el-loading-mask {
background-color: var(--color-foreground-xlight);
Expand Down
Loading