-
Notifications
You must be signed in to change notification settings - Fork 2.6k
fix: Workflow knowledge base execution supports document removal and continued import #4420
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ | |
| :before-close="close" | ||
| > | ||
| <div style="height: calc(100% - 57px)" v-loading="loading"> | ||
| <keep-alive> | ||
| <keep-alive :key="key" :include="['data_source', 'knowledge_base']"> | ||
| <component | ||
| ref="ActionRef" | ||
| :is="ak[active]" | ||
|
|
@@ -20,10 +20,9 @@ | |
| </keep-alive> | ||
| </div> | ||
| <template #footer> | ||
| <el-button :loading="loading" @click="close">{{ $t('common.cancel') }}</el-button> | ||
| <!-- <el-button v-if="active == 'result'" @click="continueImporting" :loading="loading"> | ||
| <el-button v-if="active == 'result'" @click="continueImporting"> | ||
| {{ $t('views.document.buttons.continueImporting') }} | ||
| </el-button> --> | ||
| </el-button> | ||
| <el-button | ||
| v-if="base_form_list.length > 0 && active == 'knowledge_base'" | ||
| :loading="loading" | ||
|
|
@@ -46,35 +45,29 @@ | |
| > | ||
| {{ $t('views.document.buttons.import') }} | ||
| </el-button> | ||
| <!-- <el-button | ||
| v-if="active == 'result'" | ||
| type="primary" | ||
| @click=" | ||
| router.push({ | ||
| path: `/knowledge/${id}/${folderId}/4/document`, | ||
| }) | ||
| " | ||
| >{{ $t('views.knowledge.ResultSuccess.buttons.toDocument') }}</el-button | ||
| > --> | ||
| <el-button v-if="active == 'result'" type="primary" @click="goDocument">{{ | ||
| $t('views.knowledge.ResultSuccess.buttons.toDocument') | ||
| }}</el-button> | ||
| </template> | ||
| </el-drawer> | ||
| </template> | ||
| <script setup lang="ts"> | ||
| import { computed, ref, provide, type Ref } from 'vue' | ||
| import { computed, ref, provide, type Ref, nextTick } from 'vue' | ||
| import DataSource from '@/views/knowledge-workflow/component/action/DataSource.vue' | ||
| import Result from '@/views/knowledge-workflow/component/action/Result.vue' | ||
| import applicationApi from '@/api/application/application' | ||
| import KnowledgeBase from '@/views/knowledge-workflow/component/action/KnowledgeBase.vue' | ||
| import { WorkflowType } from '@/enums/application' | ||
| import { loadSharedApi } from '@/utils/dynamics-api/shared-api.ts' | ||
|
|
||
| import { loadSharedApi } from '@/utils/dynamics-api/shared-api' | ||
| import permissionMap from '@/permission' | ||
| import { MsgError } from '@/utils/message' | ||
| import { t } from '@/locales' | ||
|
|
||
| import { useRoute, useRouter } from 'vue-router' | ||
| provide('upload', (file: any, loading?: Ref<boolean>) => { | ||
| return applicationApi.postUploadFile(file, id, 'KNOWLEDGE', loading) | ||
| }) | ||
| const key = ref<number>(0) | ||
| const router = useRouter() | ||
| const route = useRoute() | ||
| const { | ||
|
|
@@ -153,8 +146,21 @@ const upload = () => { | |
| } | ||
| } | ||
| const continueImporting = () => { | ||
| action_id.value = undefined | ||
| active.value = 'data_source' | ||
| key.value++ | ||
| action_id.value = undefined | ||
| const c_workflow = _workflow.value | ||
| _workflow.value = null | ||
| form_data.value = {} | ||
| nextTick(() => { | ||
| _workflow.value = c_workflow | ||
| }) | ||
| } | ||
| const goDocument = () => { | ||
| const newUrl = router.resolve({ | ||
| path: `/knowledge/${id}/${folderId}/4/document`, | ||
| }).href | ||
| window.open(newUrl) | ||
| } | ||
| defineExpose({ close, open }) | ||
| </script> | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code looks mostly fine, but there are a few improvements and optimizations you can consider:
Here's the revised version of your code with these considerations: <template>
<el-drawer
title="Action"
:visible.sync="$props.visible"
size="85%"
@close="handleClose"
>
<div style="height: calc(100% - 57px)" v-loading="loading">
<keep-alive :key="key" :include="['dataSource', 'knowledgeBase']">
<component
ref="actionRef"
:is="ak[active]"
@update:key="onKeyUpdate"
@update:data-base-form-list="(list) => ($emit('dbListChange', list))"
:database-forms="form_data"
@submit-data-source="handleSubmit"
/>
</keep-alive>
</div>
<template #footer>
<el-button :loading="loading" @click=" handleClose">{{ $t('common.cancel') }}</el-button>
<el-button v-if="active === 'result' && base_form_list.length > 0" type="primary" @click="continueImporting">{{ $t('views.document.buttons.continueImporting') }}</el-button>
</template>
</el-drawer>
</template>
<script setup lang="ts">
import { computed, ref, provide, type Ref, nextTick } from 'vue';
import DataSource from '@/views/knowledge-workflow/component/action/DataSource.vue';
import Result from '@/views/knowledge-workflow/component/action/Result.vue';
import applicationApi from '@/api/application/application';
import KnowledgeBase from '@/views/knowledge-workflow/component/action/KnowledgeBase.vue';
import { WorkflowType } from '@/enums/application';
import { loadSharedApi } from '@/utils/dynamics-api/shared-api.ts';
import permissionMap from '@/permission';
import { MsgError } from '@/utils/message';
import { t } from '@/locales';
import { useRoute, useRouter } from 'vue-router';
provide('upload', (file: any, loading?: Ref<boolean>) => {
return applicationApi.postUploadFile(file, id, 'KNOWLEDGE', loading);
});
const key = ref<number>(0);
const router = useRouter();
const route = useRoute();
const ak = ['dataSource', 'result'];
const active = ref<string>('data_source');
let form_data: Record<string, any> = {};
let _workflow: any | null = null;
// Utility function to handle key update after component is mounted
function onComponentMounted() {
if (_workflow && !Object.keys(form_data).length) {
Object.assign(form_data, _workflow.data || {});
}
}
// Close drawer on click outside
function closeButtonClicked(event: MouseEvent): void {
// Add custom close behavior here if needed
}
// Handle drawer closing
function handleClose(): void {
router.push({
path: `/knowledge/${id}/${folderId}/4/document`,
});
emit('close');
}
// Method to submit data source
async function handleSubmit(data: any): Promise<void> {
try {
await data.submitData(dataSourceId);
active.value = 'result';
form_data.dataSourceId = dataSourceId;
await continueImporting();
} catch (error) {
console.error("Failed to submit data source", error);
MsgError(error.message);
}
}
// Method to start importing content
function continueImporting(): void {
const c_workflow = _workflow;
_workflow = null;
form_data = {};
key.value++;
await handleSubmit({ ...c_workflow }).then(() => {
active.value = 'start_import_content';
});
}
// Go to document view
function goToDocument(): void {
const newUrl = router.resolve({
path: `/knowledge/${id}/${folderId}/4/document`,
}).href;
window.open(newUrl);
}
watch(() => [route.query.folderId], ([newFolderId]) => {
folderId.value = newFolderId!;
});
watch(_workflow, () => onComponentMounted());
// Emit events and other methods...
</script>Changes Made:
These changes should enhance readability and maintainability of your code while addressing some performance concerns related to DOM updates. |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,20 +5,20 @@ | |
| </h4> | ||
| <div class="mb-16"> | ||
| <!-- 执行结果 --> | ||
| <!-- <el-alert | ||
| v-if="isSuccess" | ||
| :title="$t('views.workflow.debug.executionSuccess')" | ||
| type="success" | ||
| show-icon | ||
| :closable="false" | ||
| /> | ||
| <el-alert | ||
| v-else | ||
| :title="$t('views.workflow.debug.executionFailed')" | ||
| type="error" | ||
| show-icon | ||
| :closable="false" | ||
| /> --> | ||
| <el-alert | ||
| v-if="state == 'SUCCESS'" | ||
| :title="$t('views.workflow.debug.executionSuccess')" | ||
| type="success" | ||
| show-icon | ||
| :closable="false" | ||
| /> | ||
| <el-alert | ||
| v-if="state == 'FAILURE'" | ||
| :title="$t('views.workflow.debug.executionFailed')" | ||
| type="error" | ||
| show-icon | ||
| :closable="false" | ||
| /> | ||
| </div> | ||
| <p class="lighter mb-8">{{ $t('chat.executionDetails.title') }}</p> | ||
| <ExecutionDetailContent :detail="detail" app-type="WORK_FLOW"></ExecutionDetailContent> | ||
|
|
@@ -45,21 +45,22 @@ const knowledge_action = ref<any>() | |
| let pollingTimer: any = null | ||
|
|
||
| const getKnowledgeWorkflowAction = () => { | ||
| if (pollingTimer == null) { | ||
| return | ||
| } | ||
| knowledgeApi | ||
| .getWorkflowAction(props.knowledge_id, props.id) | ||
| .then((ok) => { | ||
| knowledge_action.value = ok.data | ||
| }) | ||
| .finally(() => { | ||
| if (['SUCCESS', 'FAILURE', 'REVOKED'].includes(state.value)) { | ||
| stopPolling() | ||
| } else { | ||
| // 请求完成后再设置下次轮询 | ||
| pollingTimer = setTimeout(getKnowledgeWorkflowAction, 2000) | ||
| } | ||
| }) | ||
| .catch(() => { | ||
| // 错误时也继续轮询 | ||
| pollingTimer = setTimeout(getKnowledgeWorkflowAction, 2000) | ||
| }) | ||
| } | ||
|
|
||
| const stopPolling = () => { | ||
|
|
@@ -70,8 +71,7 @@ const stopPolling = () => { | |
| } | ||
|
|
||
| // 启动轮询 | ||
| getKnowledgeWorkflowAction() | ||
|
|
||
| pollingTimer = setTimeout(getKnowledgeWorkflowAction, 0) | ||
| onUnmounted(() => { | ||
| stopPolling() | ||
| }) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The provided code has several optimizations and corrections:
Here's the updated code with these improvements: @@ -6,20 +6,20 @@
</h4>
<div class="mb-16">
<!-- 执行结果 -->
- <!-- <el-alert
- v-if="isSuccess"
- :title="$t('views.workflow.debug.executionSuccess')"
- type="success"
- show-icon
- :closable="false"
- />
- <el-alert
- v-else
- :title="$t('views.workflow.debug.executionFailed')"
- type="error"
- show-icon
- :closable="false"
- /> -->
+ <el-alert
+ v-if="state === 'SUCCESS'"
+ :title="$t('views.workflow.debug.executionSuccess')"
+ type="success"
+ show-icon
+ :closable="false"
+ />
+ <el-alert
+ v-else-if="state === 'FAILURE'"
+ :title="$t('views.workflow.debug.executionFailed')"
+ type="error"
+ show-icon
+ :closable="false"
+ />
</div>
<p class="lighter mb-8">{{ $t('chat.executionDetails.title') }}</p>
<ExecutionDetailContent :detail="detail" app-type="WORK_FLOW"></ExecutionDetailContent>
@@ -45,21 +45,22 @@ const knowledge_action = ref<any>()
let pollingTimer: any = null
const getKnowledgeWorkflowAction = () => {
+ if (pollingTimer !== null) { // Corrected comparison operator
+ const state = getState(); // Adjusted assumption about current state variable name if different
knowledgeApi
.getWorkflowAction(props.knowledge_id, props.id)
.then((ok) => {
knowledge_action.value = ok.data;
})
.finally(() => {
- if(['SUCCESS', 'FAILURE', 'REVOKED'].includes(state)){
+ if (['SUCCESS', 'FAILURE', 'REVOKED'].includes(state)) {
stopPolling();
} else {
// 请求完成后再设置下次轮询
pollingTimer = setTimeout(getKnowledgeWorkflowAction, 2000);Make sure to adjust the line referencing the state variable ( |
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The provided code looks clean overall, but there's one issue related to Vue components lifecycle when dealing with
v-ifconditions and dynamically changing component keys.Potential Improvements:
Component Initialization: Ensure that the state variables (
action_id,_workflow) are correctly initialized before using them in conditional rendering.Dynamic Key Handling:
:key="key"can lead to unexpected behavior if not managed properly, especially when reusing components.Continue Importing Button Logic:
Go Document Functionality:
Here's an improved version without excessive dynamic key management, assuming the need for these features is minimal given the current context:
In this updated version, I've removed the
:key="key"from both buttons because we're only showing either a "Next Step" button or a "Submit & Go To Doc" button, making reuse unnecessary. Also, I've moved the logic for submitting forms back into separate functions, which could further improve maintainability and readability.