ADD: Univer docs
This commit is contained in:
parent
72d4423d67
commit
21f5d3a761
6629
package-lock.json
generated
6629
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,11 @@
|
|||||||
"@tiptap/extension-underline": "^3.5.2",
|
"@tiptap/extension-underline": "^3.5.2",
|
||||||
"@tiptap/starter-kit": "^3.5.2",
|
"@tiptap/starter-kit": "^3.5.2",
|
||||||
"@tiptap/vue-3": "^3.5.2",
|
"@tiptap/vue-3": "^3.5.2",
|
||||||
|
"@univerjs-pro/exchange-client": "^0.10.9",
|
||||||
|
"@univerjs/preset-docs-advanced": "^0.10.9",
|
||||||
|
"@univerjs/preset-docs-core": "^0.10.9",
|
||||||
|
"@univerjs/preset-docs-drawing": "^0.10.9",
|
||||||
|
"@univerjs/presets": "^0.10.9",
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
"@vuepic/vue-datepicker": "^11.0.2",
|
"@vuepic/vue-datepicker": "^11.0.2",
|
||||||
"apexcharts": "^5.3.5",
|
"apexcharts": "^5.3.5",
|
||||||
@ -45,5 +50,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"vite-plugin-html": "^3.2.2"
|
"vite-plugin-html": "^3.2.2"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"redi": "0.1.12"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
307
src/components/Holos/Editor/UniverDoc.vue
Normal file
307
src/components/Holos/Editor/UniverDoc.vue
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onBeforeUnmount } from 'vue';
|
||||||
|
import { UniverDocsCorePreset } from '@univerjs/preset-docs-core'
|
||||||
|
import UniverPresetDocsCoreEnUS from '@univerjs/preset-docs-core/locales/en-US'
|
||||||
|
import { UniverDocsDrawingPreset } from '@univerjs/preset-docs-drawing'
|
||||||
|
import UniverPresetDocsDrawingEnUS from '@univerjs/preset-docs-drawing/locales/en-US'
|
||||||
|
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'
|
||||||
|
|
||||||
|
import '@univerjs/preset-docs-core/lib/index.css'
|
||||||
|
import '@univerjs/preset-docs-drawing/lib/index.css'
|
||||||
|
|
||||||
|
const container = ref(null);
|
||||||
|
const showExportButton = ref(false);
|
||||||
|
|
||||||
|
let univerInstance = null;
|
||||||
|
let univerAPIInstance = null;
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
try {
|
||||||
|
const { univer, univerAPI } = createUniver({
|
||||||
|
locale: LocaleType.EN_US,
|
||||||
|
locales: {
|
||||||
|
[LocaleType.EN_US]: mergeLocales(
|
||||||
|
UniverPresetDocsCoreEnUS,
|
||||||
|
UniverPresetDocsDrawingEnUS,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
presets: [
|
||||||
|
UniverDocsCorePreset({
|
||||||
|
container: container.value,
|
||||||
|
}),
|
||||||
|
UniverDocsDrawingPreset(),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
univerAPI.createUniverDoc({});
|
||||||
|
|
||||||
|
univerInstance = univer;
|
||||||
|
univerAPIInstance = univerAPI;
|
||||||
|
|
||||||
|
// Mostrar botón cuando esté listo
|
||||||
|
showExportButton.value = true;
|
||||||
|
|
||||||
|
console.log('Univer initialized successfully with drawing support');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error initializing Univer:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
univerInstance?.dispose();
|
||||||
|
univerAPIInstance?.dispose();
|
||||||
|
univerInstance = null;
|
||||||
|
univerAPIInstance = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Función para exportar a PDF usando PDFMake
|
||||||
|
const exportToPDF = () => {
|
||||||
|
if (!univerAPIInstance || !univerInstance) {
|
||||||
|
alert('El editor no está listo aún');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('Exportando PDF...');
|
||||||
|
|
||||||
|
let docContent = '';
|
||||||
|
|
||||||
|
// Método 1: Extraer del DOM usando selectores más específicos
|
||||||
|
try {
|
||||||
|
const editorContainer = container.value;
|
||||||
|
|
||||||
|
// Buscar elementos de texto específicos de Univer (incluyendo elementos de drawing)
|
||||||
|
const textSelectors = [
|
||||||
|
'.univer-doc-text',
|
||||||
|
'.univer-paragraph',
|
||||||
|
'.univer-text-run',
|
||||||
|
'[data-text-content]',
|
||||||
|
'.docs-text-paragraph',
|
||||||
|
'.docs-text-run',
|
||||||
|
'div[contenteditable="true"]',
|
||||||
|
'div[data-univer-doc-body]',
|
||||||
|
'.univer-drawing-text', // Nuevo: texto en elementos de drawing
|
||||||
|
'.univer-shape-text' // Nuevo: texto en formas
|
||||||
|
];
|
||||||
|
|
||||||
|
let extractedText = '';
|
||||||
|
|
||||||
|
for (const selector of textSelectors) {
|
||||||
|
const elements = editorContainer.querySelectorAll(selector);
|
||||||
|
console.log(`Encontrados ${elements.length} elementos con selector: ${selector}`);
|
||||||
|
|
||||||
|
elements.forEach(element => {
|
||||||
|
const text = element.textContent || element.innerText || '';
|
||||||
|
if (text.trim() && !text.includes('arial') && !text.includes('%100')) {
|
||||||
|
extractedText += text.trim() + '\n';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (extractedText.trim()) {
|
||||||
|
console.log('Texto extraído con selector:', selector, extractedText);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
docContent = extractedText.trim();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Error con método DOM:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Método 2: Usar API de Univer si está disponible (actualizado para drawing)
|
||||||
|
if (!docContent) {
|
||||||
|
try {
|
||||||
|
const activeDoc = univerAPIInstance.getActiveDocument();
|
||||||
|
if (activeDoc) {
|
||||||
|
const snapshot = activeDoc.getSnapshot();
|
||||||
|
console.log('Snapshot completo (con drawing):', snapshot);
|
||||||
|
|
||||||
|
// Extraer texto del snapshot de manera más precisa
|
||||||
|
docContent = extractTextFromUniverSnapshot(snapshot);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Error con API method:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Método 3: Buscar en todo el DOM filtrando contenido no deseado
|
||||||
|
if (!docContent) {
|
||||||
|
try {
|
||||||
|
const allElements = container.value.querySelectorAll('*');
|
||||||
|
let allText = '';
|
||||||
|
|
||||||
|
allElements.forEach(element => {
|
||||||
|
if (element.children.length === 0) {
|
||||||
|
const text = element.textContent || element.innerText || '';
|
||||||
|
// Filtrar texto que no sea metadata
|
||||||
|
if (text &&
|
||||||
|
!text.includes('arial') &&
|
||||||
|
!text.includes('%100') &&
|
||||||
|
!text.includes('normal') &&
|
||||||
|
text.length > 1 &&
|
||||||
|
!text.match(/^[\s\n\r]*$/)) {
|
||||||
|
allText += text + ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
docContent = allText.trim();
|
||||||
|
console.log('Texto extraído por filtrado:', docContent);
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Error con método de filtrado:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preparar contenido para PDF
|
||||||
|
let content;
|
||||||
|
if (docContent && docContent.trim()) {
|
||||||
|
// Dividir por párrafos y limpiar
|
||||||
|
const paragraphs = docContent.split(/\n+/).map(p => p.trim()).filter(p => p);
|
||||||
|
|
||||||
|
if (paragraphs.length > 0) {
|
||||||
|
content = paragraphs.map(paragraph => ({
|
||||||
|
text: paragraph,
|
||||||
|
margin: [0, 0, 0, 8]
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
// Si no hay párrafos, usar el texto completo
|
||||||
|
content = [{ text: docContent, margin: [0, 0, 0, 8] }];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content = [{
|
||||||
|
text: 'Documento vacío - Escriba algo en el editor y vuelva a exportar',
|
||||||
|
style: { fontSize: 14, italics: true, color: '#666' }
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Agregar información de debug
|
||||||
|
console.log('Contenido final para PDF:', content);
|
||||||
|
|
||||||
|
// Crear el PDF
|
||||||
|
const docDefinition = {
|
||||||
|
content: content,
|
||||||
|
pageSize: 'A4',
|
||||||
|
pageMargins: [40, 60, 40, 60],
|
||||||
|
defaultStyle: {
|
||||||
|
fontSize: 12,
|
||||||
|
lineHeight: 1.4
|
||||||
|
},
|
||||||
|
styles: {
|
||||||
|
header: {
|
||||||
|
fontSize: 16,
|
||||||
|
bold: true,
|
||||||
|
margin: [0, 0, 0, 20]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generar PDF
|
||||||
|
if (typeof window.pdfMake !== 'undefined') {
|
||||||
|
window.pdfMake.createPdf(docDefinition).download('documento-univer.pdf');
|
||||||
|
console.log('PDF generado exitosamente');
|
||||||
|
} else if (typeof pdfMake !== 'undefined') {
|
||||||
|
pdfMake.createPdf(docDefinition).download('documento-univer.pdf');
|
||||||
|
console.log('PDF generado exitosamente');
|
||||||
|
} else {
|
||||||
|
alert('PDFMake no está disponible. Verifique que esté cargado correctamente.');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error al exportar PDF:', error);
|
||||||
|
alert('Error al generar el PDF: ' + error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Función mejorada para extraer texto del snapshot de Univer (actualizada para drawing)
|
||||||
|
const extractTextFromUniverSnapshot = (snapshot) => {
|
||||||
|
let text = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('Procesando snapshot:', snapshot);
|
||||||
|
|
||||||
|
// Verificar si hay body con dataStream (texto principal)
|
||||||
|
if (snapshot && snapshot.body && snapshot.body.dataStream) {
|
||||||
|
text = snapshot.body.dataStream;
|
||||||
|
console.log('Texto del dataStream:', text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verificar si hay textRuns
|
||||||
|
if (!text && snapshot && snapshot.body && snapshot.body.textRuns) {
|
||||||
|
const textRuns = snapshot.body.textRuns;
|
||||||
|
text = textRuns.map(run => {
|
||||||
|
// Extraer solo el texto, no los metadatos de formato
|
||||||
|
if (typeof run === 'string') return run;
|
||||||
|
if (run.text) return run.text;
|
||||||
|
if (run.t) return run.t;
|
||||||
|
return '';
|
||||||
|
}).join('');
|
||||||
|
console.log('Texto de textRuns:', text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verificar si hay elementos de drawing
|
||||||
|
if (snapshot && snapshot.drawings) {
|
||||||
|
console.log('Elementos de drawing encontrados:', snapshot.drawings);
|
||||||
|
// Las imágenes y formas se procesarán aquí en futuras mejoras
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si el texto contiene solo metadata, intentar buscar en otras estructuras
|
||||||
|
if (text.includes('arial') || text.includes('%100') || text.includes('normal')) {
|
||||||
|
console.log('Texto contiene metadata, buscando alternativas...');
|
||||||
|
|
||||||
|
// Buscar en paragraphs si existen
|
||||||
|
if (snapshot.body && snapshot.body.paragraphs) {
|
||||||
|
text = '';
|
||||||
|
snapshot.body.paragraphs.forEach(paragraph => {
|
||||||
|
if (paragraph.elements) {
|
||||||
|
paragraph.elements.forEach(element => {
|
||||||
|
if (element.textRun && element.textRun.content) {
|
||||||
|
text += element.textRun.content;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return text.trim();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Error extrayendo del snapshot:', error);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Exponer la función para uso externo
|
||||||
|
defineExpose({
|
||||||
|
exportToPDF
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="relative w-full h-full">
|
||||||
|
<div ref="container" class="w-full h-full min-h-96" />
|
||||||
|
|
||||||
|
<!-- Botón de exportar -->
|
||||||
|
<button
|
||||||
|
v-if="showExportButton"
|
||||||
|
@click="exportToPDF"
|
||||||
|
class="absolute top-2 right-2 px-3 py-1 bg-blue-500 text-white text-sm rounded hover:bg-blue-600 transition-colors z-10"
|
||||||
|
>
|
||||||
|
📄 Exportar PDF
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Indicador de carga -->
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="absolute top-2 right-2 px-3 py-1 bg-gray-400 text-white text-sm rounded"
|
||||||
|
>
|
||||||
|
Cargando...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
button {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,5 +1,6 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@import "../../colors.css";
|
@import "../../colors.css";
|
||||||
|
@import "./univer.css";
|
||||||
@custom-variant dark (&:where(.dark, .dark *));
|
@custom-variant dark (&:where(.dark, .dark *));
|
||||||
|
|
||||||
@theme {
|
@theme {
|
||||||
|
|||||||
31
src/css/univer.css
Normal file
31
src/css/univer.css
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* Estilos básicos para Univer */
|
||||||
|
.univer-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Contenedores de Univer */
|
||||||
|
.univer-core,
|
||||||
|
.univer-ui {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ajustes para el tema oscuro si es necesario */
|
||||||
|
.dark .univer-container {
|
||||||
|
/* Personalización para tema oscuro */
|
||||||
|
background-color: #1f2937;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Asegurar que Univer tenga el z-index correcto */
|
||||||
|
[class*="univer"] {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset de estilos que pueden interferir */
|
||||||
|
.univer-container * {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
@ -161,6 +161,12 @@ onMounted(() => {
|
|||||||
name="Maquetador de Documentos"
|
name="Maquetador de Documentos"
|
||||||
to="admin.maquetador.index"
|
to="admin.maquetador.index"
|
||||||
/>
|
/>
|
||||||
|
<Link
|
||||||
|
v-if="hasPermission('activities.index')"
|
||||||
|
icon="event"
|
||||||
|
name="Univer Docs"
|
||||||
|
to="admin.editor.index"
|
||||||
|
/>
|
||||||
</Section>
|
</Section>
|
||||||
</template>
|
</template>
|
||||||
<!-- Contenido -->
|
<!-- Contenido -->
|
||||||
|
|||||||
22
src/pages/Editor/Index.vue
Normal file
22
src/pages/Editor/Index.vue
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<script setup>
|
||||||
|
import UniverDoc from '@Holos/Editor/UniverDoc.vue';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="p-6">
|
||||||
|
<div class="mb-6">
|
||||||
|
<h1 class="text-2xl font-bold text-gray-900 dark:text-primary-dt">
|
||||||
|
Editor de Documentos
|
||||||
|
</h1>
|
||||||
|
<p class="text-gray-600 dark:text-primary-dt/70">
|
||||||
|
Editor avanzado de documentos con Univer
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white dark:bg-primary-d rounded-lg shadow-sm border border-gray-200 dark:border-primary/20">
|
||||||
|
<div class="h-[600px] p-4">
|
||||||
|
<UniverDoc />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
83
src/plugins/Univer.js
Normal file
83
src/plugins/Univer.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import { UniverDocsCorePreset } from '@univerjs/preset-docs-core'
|
||||||
|
import UniverPresetDocsCoreEnUS from '@univerjs/preset-docs-core/locales/en-US'
|
||||||
|
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'
|
||||||
|
|
||||||
|
import '@univerjs/preset-docs-core/lib/index.css'
|
||||||
|
|
||||||
|
let univerInstance = null;
|
||||||
|
let univerAPIInstance = null;
|
||||||
|
|
||||||
|
export function initializeUniver(containerElement) {
|
||||||
|
// Limpiar instancia anterior
|
||||||
|
if (univerInstance) {
|
||||||
|
try {
|
||||||
|
univerInstance.dispose();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Error disposing previous Univer instance:', error);
|
||||||
|
}
|
||||||
|
univerInstance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (univerAPIInstance) {
|
||||||
|
try {
|
||||||
|
univerAPIInstance.dispose();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Error disposing previous Univer API instance:', error);
|
||||||
|
}
|
||||||
|
univerAPIInstance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('Initializing Univer with container:', containerElement);
|
||||||
|
|
||||||
|
const { univer, univerAPI } = createUniver({
|
||||||
|
locale: LocaleType.EN_US,
|
||||||
|
locales: {
|
||||||
|
[LocaleType.EN_US]: mergeLocales(
|
||||||
|
UniverPresetDocsCoreEnUS,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
presets: [
|
||||||
|
UniverDocsCorePreset({
|
||||||
|
container: containerElement,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Crear documento inicial
|
||||||
|
univerAPI.createUniverDoc({});
|
||||||
|
|
||||||
|
univerInstance = univer;
|
||||||
|
univerAPIInstance = univerAPI;
|
||||||
|
|
||||||
|
console.log('Univer initialized successfully');
|
||||||
|
return { univer, univerAPI };
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error initializing Univer:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getUniverInstance() {
|
||||||
|
return { univer: univerInstance, univerAPI: univerAPIInstance };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function disposeUniver() {
|
||||||
|
if (univerInstance) {
|
||||||
|
try {
|
||||||
|
univerInstance.dispose();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Error disposing Univer:', error);
|
||||||
|
}
|
||||||
|
univerInstance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (univerAPIInstance) {
|
||||||
|
try {
|
||||||
|
univerAPIInstance.dispose();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Error disposing Univer API:', error);
|
||||||
|
}
|
||||||
|
univerAPIInstance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -370,6 +370,11 @@ const router = createRouter({
|
|||||||
name: 'admin.maquetador.index',
|
name: 'admin.maquetador.index',
|
||||||
component: () => import('@Pages/Maquetador/Index.vue'),
|
component: () => import('@Pages/Maquetador/Index.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
name: 'admin.editor.index',
|
||||||
|
component: () => import('@Pages/Editor/Index.vue'),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@ -24,6 +24,10 @@ export default defineConfig({
|
|||||||
'@Shared': fileURLToPath(new URL('./src/components/Shared', import.meta.url)),
|
'@Shared': fileURLToPath(new URL('./src/components/Shared', import.meta.url)),
|
||||||
'@Services': fileURLToPath(new URL('./src/services', import.meta.url)),
|
'@Services': fileURLToPath(new URL('./src/services', import.meta.url)),
|
||||||
'@Stores': fileURLToPath(new URL('./src/stores', import.meta.url)),
|
'@Stores': fileURLToPath(new URL('./src/stores', import.meta.url)),
|
||||||
}
|
},
|
||||||
}
|
dedupe: ['redi'],
|
||||||
})
|
},
|
||||||
|
optimizeDeps: {
|
||||||
|
include: ['@univerjs/preset-docs-core', '@univerjs/presets'],
|
||||||
|
},
|
||||||
|
})
|
||||||
Loading…
x
Reference in New Issue
Block a user