feat(editor): Easy AI workflow improvements (#12400)

This commit is contained in:
Milorad FIlipović 2024-12-31 14:38:32 +01:00 committed by GitHub
parent f56ad8cf49
commit 8dc691dc62
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 93 additions and 24 deletions

View file

@ -1304,6 +1304,7 @@
"nodeView.confirmMessage.debug.headline": "Unpin workflow data",
"nodeView.confirmMessage.debug.message": "Loading this execution will unpin the data currently pinned in these nodes",
"nodeView.couldntImportWorkflow": "Could not import workflow",
"nodeView.couldntLoadWorkflow.invalidWorkflowObject": "Invalid workflow object",
"nodeView.deletesTheCurrentExecutionData": "Deletes the current execution data",
"nodeView.itLooksLikeYouHaveBeenEditingSomething": "It looks like you made some edits. If you leave before saving, your changes will be lost.",
"nodeView.loadingTemplate": "Loading template",

View file

@ -32,6 +32,7 @@ import type {
IWorkflowTemplate,
NodeCreatorOpenSource,
ToggleNodeCreatorOptions,
WorkflowDataWithTemplateId,
XYPosition,
} from '@/Interface';
import type {
@ -107,6 +108,7 @@ import { getResourcePermissions } from '@/permissions';
import NodeViewUnfinishedWorkflowMessage from '@/components/NodeViewUnfinishedWorkflowMessage.vue';
import { createCanvasConnectionHandleString } from '@/utils/canvasUtilsV2';
import { isValidNodeConnectionType } from '@/utils/typeGuards';
import { EASY_AI_WORKFLOW_JSON } from '@/constants.workflows';
const LazyNodeCreation = defineAsyncComponent(
async () => await import('@/components/Node/NodeCreation.vue'),
@ -315,7 +317,13 @@ async function initializeRoute(force = false) {
isBlankRedirect.value = false;
} else if (route.name === VIEWS.TEMPLATE_IMPORT) {
const templateId = route.params.id;
const loadWorkflowFromJSON = route.query.fromJson === 'true';
if (loadWorkflowFromJSON) {
await openTemplateFromWorkflowJSON(EASY_AI_WORKFLOW_JSON);
} else {
await openWorkflowTemplate(templateId.toString());
}
} else if (isWorkflowRoute.value) {
if (!isAlreadyInitialized) {
historyStore.reset();
@ -423,6 +431,42 @@ function trackOpenWorkflowFromOnboardingTemplate() {
* Templates
*/
async function openTemplateFromWorkflowJSON(workflow: WorkflowDataWithTemplateId) {
if (!workflow.nodes || !workflow.connections) {
toast.showError(
new Error(i18n.baseText('nodeView.couldntLoadWorkflow.invalidWorkflowObject')),
i18n.baseText('nodeView.couldntImportWorkflow'),
);
await router.replace({ name: VIEWS.NEW_WORKFLOW });
return;
}
resetWorkspace();
canvasStore.startLoading();
canvasStore.setLoadingText(i18n.baseText('nodeView.loadingTemplate'));
workflowsStore.currentWorkflowExecutions = [];
executionsStore.activeExecution = null;
isBlankRedirect.value = true;
await router.replace({
name: VIEWS.NEW_WORKFLOW,
query: { templateId: workflow.meta.templateId },
});
const convertedNodes = workflow.nodes.map(workflowsStore.convertTemplateNodeToNodeUi);
workflowsStore.setConnections(workflow.connections);
await addNodes(convertedNodes);
await workflowsStore.getNewWorkflowData(workflow.name, projectsStore.currentProjectId);
uiStore.stateIsDirty = true;
canvasStore.stopLoading();
fitView();
}
async function openWorkflowTemplate(templateId: string) {
resetWorkspace();

View file

@ -101,6 +101,7 @@ import type {
AddedNodesAndConnections,
ToggleNodeCreatorOptions,
NodeFilterType,
WorkflowDataWithTemplateId,
} from '@/Interface';
import { type RouteLocation, useRoute, useRouter } from 'vue-router';
@ -180,6 +181,7 @@ import { useNpsSurveyStore } from '@/stores/npsSurvey.store';
import { getResourcePermissions } from '@/permissions';
import { useBeforeUnload } from '@/composables/useBeforeUnload';
import NodeViewUnfinishedWorkflowMessage from '@/components/NodeViewUnfinishedWorkflowMessage.vue';
import { EASY_AI_WORKFLOW_JSON } from '@/constants.workflows';
interface AddNodeOptions {
position?: XYPosition;
@ -1090,6 +1092,42 @@ export default defineComponent({
await this.$nextTick();
this.canvasStore.zoomToFit();
},
async openWorkflowTemplateFromJson(data: { workflow: WorkflowDataWithTemplateId }) {
if (!data.workflow.nodes || !data.workflow.connections) {
this.showError(
new Error(this.i18n.baseText('nodeView.couldntLoadWorkflow.invalidWorkflowObject')),
this.i18n.baseText('nodeView.couldntImportWorkflow'),
);
await this.$router.replace({ name: VIEWS.NEW_WORKFLOW });
return;
}
this.canvasStore.startLoading();
this.canvasStore.setLoadingText(this.i18n.baseText('nodeView.loadingTemplate'));
this.resetWorkspace();
this.workflowsStore.currentWorkflowExecutions = [];
this.executionsStore.activeExecution = null;
this.blankRedirect = true;
await this.$router.replace({
name: VIEWS.NEW_WORKFLOW,
query: { templateId: data.workflow.meta.templateId },
});
const convertedNodes = data.workflow.nodes.map(
this.workflowsStore.convertTemplateNodeToNodeUi,
);
await this.nodeHelpers.addNodes(convertedNodes, data.workflow.connections);
this.workflowData =
(await this.workflowsStore.getNewWorkflowData(
data.workflow.name,
this.projectsStore.currentProjectId,
)) || {};
await this.$nextTick();
this.canvasStore.zoomToFit();
this.uiStore.stateIsDirty = true;
this.canvasStore.stopLoading();
},
async openWorkflowTemplate(templateId: string) {
this.canvasStore.startLoading();
this.canvasStore.setLoadingText(this.i18n.baseText('nodeView.loadingTemplate'));
@ -3361,7 +3399,12 @@ export default defineComponent({
this.blankRedirect = false;
} else if (this.$route.name === VIEWS.TEMPLATE_IMPORT) {
const templateId = this.$route.params.id;
const loadWorkflowFromJSON = this.$route.query.fromJson === 'true';
if (loadWorkflowFromJSON) {
await this.openWorkflowTemplateFromJson({ workflow: EASY_AI_WORKFLOW_JSON });
} else {
await this.openWorkflowTemplate(templateId.toString());
}
} else {
if (
this.uiStore.stateIsDirty &&

View file

@ -7,7 +7,7 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
import { onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import type { IWorkflowDataCreate } from '@/Interface';
import { EASY_AI_WORKFLOW_JSON, SAMPLE_SUBWORKFLOW_WORKFLOW } from '@/constants.workflows';
import { SAMPLE_SUBWORKFLOW_WORKFLOW } from '@/constants.workflows';
const loadingService = useLoadingService();
const templateStore = useTemplatesStore();
@ -21,11 +21,6 @@ const openWorkflowTemplate = async (templateId: string) => {
await openSampleSubworkflow();
return;
}
if (templateId === EASY_AI_WORKFLOW_JSON.meta.templateId) {
await openEasyAIWorkflow();
return;
}
try {
loadingService.startLoading();
const template = await templateStore.getFixedWorkflowTemplate(templateId);
@ -63,21 +58,6 @@ const openWorkflowTemplate = async (templateId: string) => {
}
};
const openEasyAIWorkflow = async () => {
try {
loadingService.startLoading();
const newWorkflow = await workflowsStore.createNewWorkflow(EASY_AI_WORKFLOW_JSON);
await router.replace({
name: VIEWS.WORKFLOW,
params: { name: newWorkflow.id },
});
loadingService.stopLoading();
} catch (e) {
await router.replace({ name: VIEWS.NEW_WORKFLOW });
loadingService.stopLoading();
}
};
const openSampleSubworkflow = async () => {
try {
loadingService.startLoading();

View file

@ -270,8 +270,9 @@ const openAIWorkflow = async (source: string) => {
{ withPostHog: true },
);
await router.push({
name: VIEWS.WORKFLOW_ONBOARDING,
name: VIEWS.TEMPLATE_IMPORT,
params: { id: EASY_AI_WORKFLOW_JSON.meta.templateId },
query: { fromJson: 'true' },
});
};