Nextcloud-App/src/Ticket.vue

151 lines
3.8 KiB
Vue

<template>
<div class="single-ticket">
<div class="header-bar">
<button @click="back">
{{ t('upschooling', 'Zurück') }}
</button>
<button @click="save">
{{ t('upschooling', 'Speichern') }}
</button>
</div>
<h2>Ticket "ding"</h2>
<KeyValueTable :data-rows="{Id: ticket.ticketId, Name: ticket.title, Status: ticket.status, Geaendert: toLocaleDate(ticket.lastModified)}" />
<br>
<label for="description">{{ t('upschooling', 'Beschreibung') }}</label>
<textarea id="description" v-model.trim.lazy="description" rows="15" />
<br>
<button @click="save">
{{ t('upschooling', 'Speichern') }}
</button>
<hr>
<iframe id="element-web-frame"
src="about:blank"
title="Embedded Element Web"
width="100%"
height="400" />
</div>
</template>
<script>
import KeyValueTable from './components/KeyValueTable'
import axios from '@nextcloud/axios'
export default {
name: 'Ticket',
components: { KeyValueTable },
props: {
ticket: {
type: Object,
default() {
return {}
},
},
},
data() {
return {
description: this.ticket.description,
}
},
mounted() {
/** @type {HTMLIFrameElement} */
const elementWebFrame = document.getElementById('element-web-frame')
this.loadChat(elementWebFrame).catch((err) => {
console.error('Could not load Element Web in iframe', err)
elementWebFrame.src = 'about:blank'
elementWebFrame.onload = function() {
const textElement = elementWebFrame.contentDocument.createElement('strong')
textElement.innerText = 'Element Web konnte nicht geladen werden.'
elementWebFrame.contentDocument.body.appendChild(textElement)
elementWebFrame.onload = undefined
}
})
},
methods: {
toLocaleDate(timestamp) {
const date = new Date(timestamp)
return date.toLocaleString()
},
save() {
this.$emit('save-ticket', this.ticket.ticketId, {}) // TODO: give it only the changed data
},
back() {
this.$emit('show-ticket-list')
},
async loadChat(elementWebFrame) {
const matrixInfoResponse = await axios.get(
`api/v1/tickets/${this.ticket.ticketId}/chat`,
{ headers: { Accept: 'application/json' } },
)
if (matrixInfoResponse.status !== 200) {
throw Error(`Received unexpected status code ${matrixInfoResponse.status} for fetching matrix chat data`)
}
if (!matrixInfoResponse.data) {
throw Error('Did not receive any matrix chat data')
}
if (typeof matrixInfoResponse.data !== 'object') {
throw Error('Unexpected return value for fetching matrix chat data')
}
const loginPromise = new Promise(function(resolve, reject) {
const tryLogin = (elementWebFrame, matrixInfo, round) => {
if (elementWebFrame.contentWindow.mxLoginWithAccessToken === undefined) {
console.warn('Couldn\'t login in round ' + round)
setTimeout(() => {
tryLogin(elementWebFrame, matrixInfo, round + 1)
}, 1000)
} else {
elementWebFrame.contentWindow.mxLoginWithAccessToken(
matrixInfo.matrixServerUrl,
matrixInfo.matrixAccessToken,
).then(resolve).catch(reject)
}
}
elementWebFrame.onload = function() {
elementWebFrame.onload = undefined
tryLogin(elementWebFrame, matrixInfoResponse.data, 1)
}
})
// load Element Web
elementWebFrame.src = '/upschooling/element-web/'
loginPromise.then(() => {
console.warn('LOGGED IN')
elementWebFrame.contentWindow.mxDispatcher.dispatch({
action: 'view_home_page',
justRegistered: false,
})
elementWebFrame.contentWindow.mxDispatcher.dispatch({
action: 'view_room',
room_id: matrixInfoResponse.data.matrixRoom,
})
}).catch(console.error)
},
},
}
</script>
<style scoped>
textarea {
width: 100%;
margin: 0;
resize: vertical;
}
.placeholder {
height: 400px;
width: 100%;
background: #f0f0f0;
}
.header-bar {
display: flex;
width: 100%;
flex-direction: row-reverse;
}
</style>