Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rootjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"eslint": "9.15.0",
"js-base64": "^3.7.7",
"prettier": "3.3.3",
"qs": "^6.14.0",
"sass": "1.81.0",
"typescript": "~5.6.3",
"vite": "5.4.11",
Expand Down
133 changes: 45 additions & 88 deletions rootjs/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,104 +1,61 @@
<template>
<main id="rootjs-main" class="oc-height-1-1">
<div class="oc-flex root-viewer oc-height-1-1">
<div id="web-nav-sidebar" class="root-sidebar app-navigation oc-app-navigation-expanded">
<select id="mode-select" v-model="viewMode" @change="renderViewer">
<option v-for="item in items" :key="item" :value="item">
{{ item }}
</option>
</select>
<div id="treeViewer"></div>
</div>
<div id="mainViewer" class="oc-flex oc-height-1-1 app-content oc-width-1-1"></div>
</div>
</main>
<iframe id="rootjs-viewer" ref="rootJsViewer" :src="iframeSource" title="ROOTJS Viewer" />
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue'
import qs from 'qs'
import { defineComponent, unref, ref, onMounted, PropType } from 'vue'
import { Resource, SpaceResource } from '@ownclouders/web-client'
import { useClientService, useAuthStore, useUserStore, AppConfigObject } from '@ownclouders/web-pkg'

export default defineComponent({
name: 'ROOTJSViewer',
props: {
url: {
type: String,
space: {
type: SpaceResource,
required: true
}
},
resource: {
type: Resource,
required: true
},
applicationConfig: {
type: Object as PropType<AppConfigObject>,
required: true,
// hack so the correct type is being used for the app config
default: (): AppConfigObject => undefined
},
},
setup(props) {
const davURL = computed(() => {
return props.url
const clientService = useClientService()
const { user } = useUserStore()
const authStore = useAuthStore()

const { url = 'https://root.cern/js/latest' } = props.applicationConfig

const iframeSource = ref('')

onMounted(async () => {
// get direct url to file and clean query parameters
const signedUrl = await clientService.webdav.getFileUrl(props.space, props.resource, {
isUrlSigningEnabled: true,
username: user.id
})
const fileUrl = new URL(signedUrl)
fileUrl.search = '' // remmove signature...

const query = qs.stringify({
// file: `${fileUrl.href}?access_token=${authStore.accessToken}`,
noselect: '',
topname: props.resource.name,
info: 'ROOT viewer',
})
iframeSource.value = `${url}?${query}&file=${fileUrl.href}?access_token=${authStore.accessToken}`
// iframeSource.value = `${url}?${query}`
})

return {
davURL
}
},
data: () => ({
loading: true,
error: false,
items: ['simple', 'tabs', 'collapsible', 'grid 2x2', 'grid 3x3', 'grid 4x4'],
viewMode: null,
painter: null,
isPublic: false
}),
created() {
this.viewMode = this.items[0]
},
mounted: function () {
require.config({
onNodeCreated: function(node){
node.setAttribute('crossorigin', 'anonymous')
}
})
require(['//root.cern/js/7.8.2/scripts/JSRoot.core.min.js'], this.renderViewer, this.showError)
},
methods: {
rootFile() {
return fetch(this.davURL).then((resp) => {
if (resp.ok) {
return resp.arrayBuffer()
} else {
return Promise.reject('error code: ' + resp.status)
}
})
},
renderViewer: function () {
if (this.painter !== null) {
this.painter.cleanup()
}
this.rootFile()
.then((file) => {
JSROOT.require('hierarchy').then(() => {
this.painter = new JSROOT.HierarchyPainter('treeViewer', 'treeViewer')
this.painter.setDisplay(this.viewMode, 'mainViewer')
this.painter.openRootFile(file).then(() => (this.loading = false))
})
})
.catch((error) => {
this.showError()
console.log(error)
})
},
showError: function () {
// FIXME waiting for owncloud to implement a way to show error
console.error('showError')
iframeSource
}
}
})
</script>

<style>
#rootjs-main {
/* FIXME make app compatible with dark mode */
background-color: white !important;
}
.root-sidebar {
display: block !important;
padding: 10px;
overflow: auto !important;
box-sizing: border-box;
}
#mainViewer {
padding: 10px;
}
</style>
</script>