migrate from github
This commit is contained in:
@@ -0,0 +1,306 @@
|
||||
import { ref } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import {
|
||||
createDocument as createDocumentApi,
|
||||
createTemplate as createTemplateApi,
|
||||
deleteDocument as deleteDocumentApi,
|
||||
updateDocumentMeta
|
||||
} from '@/services/api';
|
||||
import { useApiAction } from '@/composables/actions/useApiAction';
|
||||
import { DEFAULT_DOCUMENT_TYPE, normalizeDocumentType } from '@/utils/documentType';
|
||||
|
||||
export function useDocumentEditorActions({
|
||||
t,
|
||||
router,
|
||||
kbId,
|
||||
docId,
|
||||
currentDocType,
|
||||
currentDocTitle,
|
||||
editorContent,
|
||||
directoryTree,
|
||||
updateTreeNodeTitle,
|
||||
fetchDocuments
|
||||
}) {
|
||||
const { runWithLoading } = useApiAction({ t });
|
||||
|
||||
const isEditingTitle = ref(false);
|
||||
const pendingTitle = ref('');
|
||||
const savingTitle = ref(false);
|
||||
const renamingNode = ref(false);
|
||||
|
||||
const showCreateDialog = ref(false);
|
||||
const creatingLoading = ref(false);
|
||||
const pendingParentId = ref(null);
|
||||
const selectedDocumentType = ref(DEFAULT_DOCUMENT_TYPE);
|
||||
|
||||
const savingTemplate = ref(false);
|
||||
const showTemplateDialog = ref(false);
|
||||
const templateDialogInit = ref({
|
||||
name: '',
|
||||
description: '',
|
||||
scope: 'own',
|
||||
tags: '',
|
||||
content: ''
|
||||
});
|
||||
|
||||
const openCreateDocumentDialog = (parentId = null, documentType = DEFAULT_DOCUMENT_TYPE) => {
|
||||
pendingParentId.value = parentId;
|
||||
selectedDocumentType.value = normalizeDocumentType(documentType);
|
||||
showCreateDialog.value = true;
|
||||
};
|
||||
|
||||
const cancelCreateDocument = () => {
|
||||
showCreateDialog.value = false;
|
||||
};
|
||||
|
||||
const createDocument = async (payload) => {
|
||||
const title = payload?.title?.trim() || t('document.untitledDefaultTitle');
|
||||
await runWithLoading(
|
||||
creatingLoading,
|
||||
async () => {
|
||||
const isPersonal = kbId.value === 'personal';
|
||||
const requestBody = {
|
||||
title,
|
||||
type: normalizeDocumentType(payload?.type || selectedDocumentType.value),
|
||||
container_type: isPersonal ? 'own' : 'knowledge_base',
|
||||
is_public: false
|
||||
};
|
||||
if (!isPersonal) {
|
||||
requestBody.knowledge_base_external_id = kbId.value;
|
||||
}
|
||||
if (payload?.parent_external_id) {
|
||||
requestBody.parent_external_id = payload.parent_external_id;
|
||||
} else if (pendingParentId.value) {
|
||||
requestBody.parent_external_id = pendingParentId.value;
|
||||
}
|
||||
if (payload?.template) {
|
||||
requestBody.template_id = payload.template;
|
||||
}
|
||||
return createDocumentApi(requestBody);
|
||||
},
|
||||
{
|
||||
context: 'createDocument',
|
||||
errorMessage: t('knowledgeBase.createDocumentError'),
|
||||
onSuccess: async (response) => {
|
||||
const isPersonal = kbId.value === 'personal';
|
||||
showCreateDialog.value = false;
|
||||
pendingParentId.value = null;
|
||||
await fetchDocuments();
|
||||
if (response?.external_id) {
|
||||
if (isPersonal) {
|
||||
router.push(`/mydocument/${response.external_id}`);
|
||||
} else {
|
||||
router.push(`/knowledge-base/${kbId.value}/document/${response.external_id}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const handleCreateFromTree = (payload) => {
|
||||
if (!payload) {
|
||||
openCreateDocumentDialog(null, DEFAULT_DOCUMENT_TYPE);
|
||||
return;
|
||||
}
|
||||
if (typeof payload === 'object' && ('target' in payload || 'type' in payload)) {
|
||||
openCreateDocumentDialog(
|
||||
payload?.target?.id || null,
|
||||
payload?.type || DEFAULT_DOCUMENT_TYPE
|
||||
);
|
||||
return;
|
||||
}
|
||||
openCreateDocumentDialog(payload?.id || null, DEFAULT_DOCUMENT_TYPE);
|
||||
};
|
||||
|
||||
const deletingDocument = ref(false);
|
||||
|
||||
const handleDeleteDocument = async (target) => {
|
||||
const targetId = target?.id || docId.value;
|
||||
if (!targetId) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await ElMessageBox.confirm(t('document.deleteDocumentConfirm'), t('document.deleteDocument'), {
|
||||
confirmButtonText: t('button.confirm'),
|
||||
cancelButtonText: t('button.cancel'),
|
||||
type: 'warning'
|
||||
});
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
await runWithLoading(
|
||||
deletingDocument,
|
||||
() => deleteDocumentApi(targetId),
|
||||
{
|
||||
context: 'deleteDocument',
|
||||
successMessage: t('document.deleteSuccess'),
|
||||
errorMessage: t('common.requestFailed'),
|
||||
onSuccess: async () => {
|
||||
await fetchDocuments();
|
||||
if (String(targetId) === String(docId.value)) {
|
||||
const isPersonal = kbId.value === 'personal';
|
||||
if (isPersonal) {
|
||||
router.push('/mydocuments');
|
||||
} else {
|
||||
router.push(`/knowledge-base/${kbId.value}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const handleRenameFromTree = async (payload) => {
|
||||
const targetNode = payload?.data;
|
||||
const nextTitle = payload?.title?.trim?.() || '';
|
||||
if (!targetNode?.id || !nextTitle) {
|
||||
ElMessage.error(t('knowledgeBase.titleRequired'));
|
||||
return;
|
||||
}
|
||||
const targetId = String(targetNode.id);
|
||||
const currentTitle = String(targetNode.label || '').trim();
|
||||
if (nextTitle === currentTitle) {
|
||||
return;
|
||||
}
|
||||
|
||||
await runWithLoading(
|
||||
renamingNode,
|
||||
() => updateDocumentMeta(targetId, { title: nextTitle }),
|
||||
{
|
||||
context: 'renameDocumentFromTree',
|
||||
errorMessage: t('common.requestFailed'),
|
||||
onSuccess: () => {
|
||||
updateTreeNodeTitle(directoryTree.value, targetId, nextTitle);
|
||||
if (String(docId.value || '') === targetId) {
|
||||
currentDocTitle.value = nextTitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const startEditTitle = async () => {
|
||||
if (!docId.value) {
|
||||
return;
|
||||
}
|
||||
isEditingTitle.value = true;
|
||||
pendingTitle.value = currentDocTitle.value || '';
|
||||
};
|
||||
|
||||
const cancelEditTitle = () => {
|
||||
isEditingTitle.value = false;
|
||||
pendingTitle.value = '';
|
||||
};
|
||||
|
||||
const commitTitle = async () => {
|
||||
if (!isEditingTitle.value) {
|
||||
return;
|
||||
}
|
||||
const nextTitle = pendingTitle.value.trim();
|
||||
if (!nextTitle) {
|
||||
ElMessage.error(t('knowledgeBase.titleRequired'));
|
||||
return;
|
||||
}
|
||||
if (nextTitle === currentDocTitle.value) {
|
||||
cancelEditTitle();
|
||||
return;
|
||||
}
|
||||
if (!docId.value) {
|
||||
cancelEditTitle();
|
||||
return;
|
||||
}
|
||||
await runWithLoading(
|
||||
savingTitle,
|
||||
() => updateDocumentMeta(docId.value, { title: nextTitle }),
|
||||
{
|
||||
context: 'updateDocumentMeta',
|
||||
errorMessage: t('common.requestFailed'),
|
||||
onSuccess: () => {
|
||||
currentDocTitle.value = nextTitle;
|
||||
updateTreeNodeTitle(directoryTree.value, docId.value, nextTitle);
|
||||
cancelEditTitle();
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const openCreateTemplateDialog = () => {
|
||||
const defaultScope = kbId.value && kbId.value !== 'personal' ? 'knowledge_base' : 'own';
|
||||
templateDialogInit.value = {
|
||||
name: currentDocTitle.value || t('templates.untitled'),
|
||||
description: '',
|
||||
scope: defaultScope,
|
||||
tags: '',
|
||||
content: editorContent.value || ''
|
||||
};
|
||||
showTemplateDialog.value = true;
|
||||
};
|
||||
|
||||
const handleHeaderCommand = (command) => {
|
||||
if (command === 'create_template') {
|
||||
openCreateTemplateDialog();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const submitCreateTemplate = async (payload) => {
|
||||
if (!editorContent.value || !editorContent.value.trim()) {
|
||||
ElMessage.error(t('templates.emptyContent'));
|
||||
return;
|
||||
}
|
||||
|
||||
await runWithLoading(
|
||||
savingTemplate,
|
||||
async () => {
|
||||
const requestBody = {
|
||||
target_container: payload.scope,
|
||||
type: normalizeDocumentType(currentDocType?.value || DEFAULT_DOCUMENT_TYPE),
|
||||
template_content: JSON.stringify({
|
||||
name: payload.name,
|
||||
description: payload.description,
|
||||
content: editorContent.value,
|
||||
tags: payload.tags || []
|
||||
})
|
||||
};
|
||||
if (payload.scope === 'knowledge_base' && kbId.value && kbId.value !== 'personal') {
|
||||
requestBody.knowledge_base_id = kbId.value;
|
||||
}
|
||||
await createTemplateApi(requestBody);
|
||||
},
|
||||
{
|
||||
context: 'createTemplate',
|
||||
successMessage: t('templates.saveSuccess'),
|
||||
errorMessage: t('templates.saveFailed'),
|
||||
onSuccess: () => {
|
||||
showTemplateDialog.value = false;
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
isEditingTitle,
|
||||
pendingTitle,
|
||||
showCreateDialog,
|
||||
creatingLoading,
|
||||
pendingParentId,
|
||||
selectedDocumentType,
|
||||
savingTemplate,
|
||||
showTemplateDialog,
|
||||
templateDialogInit,
|
||||
openCreateDocumentDialog,
|
||||
cancelCreateDocument,
|
||||
createDocument,
|
||||
handleCreateFromTree,
|
||||
handleDeleteDocument,
|
||||
handleRenameFromTree,
|
||||
startEditTitle,
|
||||
cancelEditTitle,
|
||||
commitTitle,
|
||||
handleHeaderCommand,
|
||||
submitCreateTemplate
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user