Skip to content
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

[draw.io] Deployment config + .vsdx support #4337

Merged
merged 14 commits into from
Dec 9, 2020
Merged
122 changes: 105 additions & 17 deletions apps/draw-io/src/DrawIoEditor.vue
Original file line number Diff line number Diff line change
@@ -1,47 +1,68 @@
<template>
<iframe id="drawio-editor" ref="drawIoEditor" :src="iframeSource"></iframe>
<div>
<oc-spinner
v-if="loading"
:aria-label="this.$gettext('Loading media')"
class="uk-position-center"
size="xlarge"
/>
<iframe v-else id="drawio-editor" ref="drawIoEditor" :src="iframeSource" />
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
import { basename } from 'path'
import queryString from 'query-string'
import moment from 'moment'

export default {
name: 'DrawIoEditor',
data: () => ({
loading: true,
filePath: '',
fileExtension: '',
isReadOnly: null,
currentETag: null
}),
computed: {
...mapGetters(['getToken']),
loading() {
return this.content === ''
config() {
const { url = 'https://embed.diagrams.net', theme = 'minimal', autosave = false } =
this.$store.state.apps.fileEditors.find(editor => editor.app === 'draw-io').config || {}
return { url, theme, autosave: autosave ? 1 : 0 }
},
iframeSource() {
const query = queryString.stringify({
embed: 1,
chrome: this.isReadOnly ? 0 : 1,
picker: 0,
stealth: 1,
spin: 1,
proto: 'json',
ui: 'minimal'
ui: this.config.theme
})

return 'https://www.draw.io?' + query
return `${this.config.url}?${query}`
}
},
created() {
this.filePath = this.$route.params.filePath

this.fileExtension = this.filePath.split('.').pop()
this.checkPermissions()
window.addEventListener('message', event => {
console.log(event)
if (event.data.length > 0) {
var payload = JSON.parse(event.data)
if (payload.event === 'init') {
this.load()
} else if (payload.event === 'save') {
this.save(payload)
} else if (payload.event === 'exit') {
this.exit()
switch (payload.event) {
case 'init':
this.fileExtension === 'vsdx' ? this.importVisio() : this.load()
break
case 'autosave':
case 'save':
this.save(payload)
break
case 'exit':
this.exit()
break
}
}
})
Expand All @@ -50,15 +71,25 @@ export default {
...mapActions(['showMessage']),
error(error) {
this.showMessage({
title: this.$gettext('PDF could not be loaded…'),
title: this.$gettext('The diagram could not be loaded…'),
desc: error,
status: 'danger',
autoClose: {
enabled: true
}
})
},

checkPermissions() {
this.$client.files
.fileInfo(this.filePath, ['{http://owncloud.org/ns}permissions'])
.then(v => {
this.isReadOnly = v.fileInfo['{http://owncloud.org/ns}permissions'].indexOf('W') === -1
this.loading = false
})
.catch(error => {
this.error(error)
})
},
load() {
this.$client.files
.getFileContents(this.filePath, { resolveWithResponseObject: true })
Expand All @@ -67,7 +98,8 @@ export default {
this.$refs.drawIoEditor.contentWindow.postMessage(
JSON.stringify({
action: 'load',
xml: resp.body
xml: resp.body,
autosave: this.config.autosave
}),
'*'
)
Expand All @@ -76,20 +108,77 @@ export default {
this.error(error)
})
},
importVisio() {
const url = this.$client.files.getFileUrl(this.filePath)
const headers = new Headers({
Authorization: 'Bearer ' + this.getToken,
'X-Requested-With': 'XMLHttpRequest'
})
const getDescription = () =>
this.$gettextInterpolate(
'The diagram will open as a new .drawio file: %{file}',
{ file: basename(this.filePath) },
true
)
// Change the working file after the import so the original file is not overwritten
this.filePath += `_${this.getTimestamp()}.drawio`
this.showMessage({
title: this.$gettext('Diagram imported'),
desc: getDescription(),
autoClose: {
enabled: true
}
})
fetch(url, { headers })
Copy link
Collaborator

@LukasHirt LukasHirt Nov 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried with getFileContent, but it looks like we cannot specify the responsetype. Drawio is able to handle the vsdx file as base64, so we need the file itself insted of its content. Also tried to re-create the file from its binary content, but I could not find a way to do so, the resultant file was always different.

.then(resp => {
// Not setting `currentETag` on imports allows to create new files
// otherwise the ETag comparison fails with a 412 during the autosave/save event
// this.currentETag = resp.headers.get('etag')
return resp.arrayBuffer()
})
.then(arrayBuffer => {
var blob = new Blob([arrayBuffer], { type: 'application/vnd.visio' })
var reader = new FileReader()
reader.onloadend = () => {
this.$refs.drawIoEditor.contentWindow.postMessage(
JSON.stringify({
action: 'load',
xml: reader.result,
autosave: this.config.autosave
}),
'*'
)
}
reader.readAsDataURL(blob)
})
.catch(error => {
this.error(error)
})
},
save(payload) {
this.$client.files
.putFileContents(this.filePath, payload.xml, {
previousEntityTag: this.currentETag
})
.then(resp => {
this.currentETag = resp.ETag
this.$refs.drawIoEditor.contentWindow.postMessage(
JSON.stringify({
action: 'status',
modified: false
}),
'*'
)
})
.catch(error => {
this.error(error)
})
},
exit() {
window.close()
},
getTimestamp() {
return moment().format('YYYYMMDD[T]HHmmss')
}
}
}
Expand All @@ -107,6 +196,5 @@ export default {
margin: 0;
padding: 0;
overflow: hidden;
z-index: 999999;
}
</style>
5 changes: 5 additions & 0 deletions apps/draw-io/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ const appInfo = {
'files-shared-with-me',
'public-files'
]
},
{
extension: 'vsdx',
newTab: true,
routeName: 'draw-io-edit'
}
]
}
Expand Down
73 changes: 34 additions & 39 deletions apps/draw-io/webpack.common.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,53 @@
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const webpack = require('webpack')

module.exports = {
plugins: [
new VueLoaderPlugin()
],
plugins: [new VueLoaderPlugin(), new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)],
entry: {
'draw-io': [
'core-js/modules/es6.promise',
'core-js/modules/es6.array.iterator',
'./src/app.js'
]
'draw-io': ['core-js/modules/es6.promise', 'core-js/modules/es6.array.iterator', './src/app.js']
},
output: {
publicPath: 'apps/draw-io/',
chunkFilename: '[name].draw-io.chunk.js',
filename: 'draw-io.bundle.js'
},
module: {
rules: [{
test: /\.js?$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
rootMode: 'upward'
}
}, {
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.jsx?$/,
include: /node_modules\/(?=(query-string|split-on-first|strict-uri-encode)\/).*/,
use: {
rules: [
{
test: /\.js?$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
targets: {
ie: '11'
rootMode: 'upward'
}
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.jsx?$/,
include: /node_modules\/(?=(query-string|split-on-first|strict-uri-encode)\/).*/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
targets: {
ie: '11'
}
}
}
]
]
]
}
}
},
{
test: /\.css$/,
use: ['vue-style-loader', 'css-loader']
}
},
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
}]
]
}
}
8 changes: 8 additions & 0 deletions changelog/unreleased/drawio-custom-configuration
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Enhancement: Add custom configuration to the draw.io app

Added mechanism to specify custom configuration instead of using a hardcoded
one. The new settings include support for a custom draw.io server, enabling
autosave and using a specific theme.

https://github.com/owncloud/phoenix/pull/4337
https://github.com/owncloud/phoenix/issues/4328
8 changes: 8 additions & 0 deletions changelog/unreleased/drawio-vsdx-support
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Enhancement: Add support for .vsdx files in the draw.io app

Added the support to open .vsdx files (Microsoft Visio Files) directly
from OwnCloud, instead of creating a new diagram to import the file from
local storage.

https://github.com/owncloud/phoenix/pull/4337
https://github.com/owncloud/phoenix/issues/4327