81 lines
2.4 KiB
JavaScript
81 lines
2.4 KiB
JavaScript
|
import axios from '~/lib/utils/axios_utils';
|
|||
|
|
|||
|
/**
|
|||
|
* A set of functions to decouple the content_editor component from
|
|||
|
* the draw.io editor.
|
|||
|
* It allows the draw.io editor to obtain a selected drawio_diagram
|
|||
|
* and replace it or insert a new drawio_diagram node without coupling
|
|||
|
* the drawio_editor to the Content Editor implementation details
|
|||
|
* *
|
|||
|
* @param {Object} params Factory function parameters
|
|||
|
* @param {Object} params.tiptapEditor See https://tiptap.dev/api/editor
|
|||
|
* @param {String} params.drawioNodeName Name of the drawio_diagram node in
|
|||
|
* the ProseMirror document
|
|||
|
* @param {String} params.uploadsPath API endpoint to upload files
|
|||
|
* @param {Object} params.assetResolver See
|
|||
|
* app/assets/javascripts/content_editor/services/asset_resolver.js
|
|||
|
*
|
|||
|
* @returns A content_editor_facade object with operations
|
|||
|
* to get a selected diagram, upload a diagram, insert a new one in the
|
|||
|
* Content Editor, and update an existing’s diagram URL.
|
|||
|
*/
|
|||
|
export const create = ({ tiptapEditor, drawioNodeName, uploadsPath, assetResolver }) => ({
|
|||
|
getDiagram: async () => {
|
|||
|
const { node } = tiptapEditor.state.selection;
|
|||
|
|
|||
|
if (!node || node.type.name !== drawioNodeName) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
const { src } = node.attrs;
|
|||
|
const response = await axios.get(src, { responseType: 'text' });
|
|||
|
const diagramSvg = response.data;
|
|||
|
const contentType = response.headers['content-type'];
|
|||
|
const filename = src.split('/').pop();
|
|||
|
|
|||
|
return {
|
|||
|
diagramURL: src,
|
|||
|
filename,
|
|||
|
diagramSvg,
|
|||
|
contentType,
|
|||
|
};
|
|||
|
},
|
|||
|
updateDiagram: async ({ uploadResults: { file_path: canonicalSrc } }) => {
|
|||
|
const src = await assetResolver.resolveUrl(canonicalSrc);
|
|||
|
|
|||
|
tiptapEditor
|
|||
|
.chain()
|
|||
|
.focus()
|
|||
|
.updateAttributes(drawioNodeName, {
|
|||
|
src,
|
|||
|
canonicalSrc,
|
|||
|
})
|
|||
|
.run();
|
|||
|
},
|
|||
|
insertDiagram: async ({ uploadResults: { file_path: canonicalSrc } }) => {
|
|||
|
const src = await assetResolver.resolveUrl(canonicalSrc);
|
|||
|
|
|||
|
tiptapEditor
|
|||
|
.chain()
|
|||
|
.focus()
|
|||
|
.insertContent({
|
|||
|
type: drawioNodeName,
|
|||
|
attrs: {
|
|||
|
src,
|
|||
|
canonicalSrc,
|
|||
|
},
|
|||
|
})
|
|||
|
.run();
|
|||
|
},
|
|||
|
uploadDiagram: async ({ filename, diagramSvg }) => {
|
|||
|
const blob = new Blob([diagramSvg], { type: 'image/svg+xml' });
|
|||
|
const formData = new FormData();
|
|||
|
|
|||
|
formData.append('file', blob, filename);
|
|||
|
|
|||
|
const response = await axios.post(uploadsPath, formData);
|
|||
|
|
|||
|
return response.data;
|
|||
|
},
|
|||
|
});
|