80 lines
2.4 KiB
JavaScript
80 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;
|
||
},
|
||
});
|