Status integration
Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
parent
ae6be0c110
commit
3be3c34e39
|
@ -1,6 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="app-dashboard">
|
<div id="app-dashboard">
|
||||||
<h2>{{ greeting.icon }} {{ greeting.text }}</h2>
|
<h2>{{ greeting.icon }} {{ greeting.text }}</h2>
|
||||||
|
<div class="statuses">
|
||||||
|
<div v-for="status in registeredStatus"
|
||||||
|
:id="'status-' + status"
|
||||||
|
:key="status"
|
||||||
|
:ref="'status-' + status" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<Draggable v-model="layout" class="panels" @end="saveLayout">
|
<Draggable v-model="layout" class="panels" @end="saveLayout">
|
||||||
<div v-for="panelId in layout" :key="panels[panelId].id" class="panel">
|
<div v-for="panelId in layout" :key="panels[panelId].id" class="panel">
|
||||||
|
@ -73,7 +79,9 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
timer: new Date(),
|
timer: new Date(),
|
||||||
|
registeredStatus: [],
|
||||||
callbacks: {},
|
callbacks: {},
|
||||||
|
callbacksStatus: {},
|
||||||
panels,
|
panels,
|
||||||
firstRun,
|
firstRun,
|
||||||
displayName: getCurrentUser()?.displayName,
|
displayName: getCurrentUser()?.displayName,
|
||||||
|
@ -81,6 +89,7 @@ export default {
|
||||||
layout: loadState('dashboard', 'layout').filter((panelId) => panels[panelId]),
|
layout: loadState('dashboard', 'layout').filter((panelId) => panels[panelId]),
|
||||||
modal: false,
|
modal: false,
|
||||||
appStoreUrl: generateUrl('/settings/apps'),
|
appStoreUrl: generateUrl('/settings/apps'),
|
||||||
|
statuses: {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -89,18 +98,18 @@ export default {
|
||||||
const shouldShowName = this.displayName && this.uid !== this.displayName
|
const shouldShowName = this.displayName && this.uid !== this.displayName
|
||||||
|
|
||||||
if (time > 18) {
|
if (time > 18) {
|
||||||
return { icon: '🌙', text: shouldShowName ? t('dashboard', 'Good evening, {name}', { name: this.name }) : t('dashboard', 'Good evening') }
|
return { icon: '🌙', text: shouldShowName ? t('dashboard', 'Good evening, {name}', { name: this.displayName }) : t('dashboard', 'Good evening') }
|
||||||
}
|
}
|
||||||
if (time > 12) {
|
if (time > 12) {
|
||||||
return { icon: '☀', text: shouldShowName ? t('dashboard', 'Good afternoon, {name}', { name: this.name }) : t('dashboard', 'Good afternoon') }
|
return { icon: '☀', text: shouldShowName ? t('dashboard', 'Good afternoon, {name}', { name: this.displayName }) : t('dashboard', 'Good afternoon') }
|
||||||
}
|
}
|
||||||
if (time === 12) {
|
if (time === 12) {
|
||||||
return { icon: '🍽', text: shouldShowName ? t('dashboard', 'Time for lunch, {name}', { name: this.name }) : t('dashboard', 'Time for lunch') }
|
return { icon: '🍽', text: shouldShowName ? t('dashboard', 'Time for lunch, {name}', { name: this.displayName }) : t('dashboard', 'Time for lunch') }
|
||||||
}
|
}
|
||||||
if (time > 5) {
|
if (time > 5) {
|
||||||
return { icon: '🌄', text: shouldShowName ? t('dashboard', 'Good morning, {name}', { name: this.name }) : t('dashboard', 'Good morning') }
|
return { icon: '🌄', text: shouldShowName ? t('dashboard', 'Good morning, {name}', { name: this.displayName }) : t('dashboard', 'Good morning') }
|
||||||
}
|
}
|
||||||
return { icon: '🦉', text: shouldShowName ? t('dashboard', 'Have a night owl, {name}', { name: this.name }) : t('dashboard', 'Have a night owl') }
|
return { icon: '🦉', text: shouldShowName ? t('dashboard', 'Have a night owl, {name}', { name: this.displayName }) : t('dashboard', 'Have a night owl') }
|
||||||
},
|
},
|
||||||
isActive() {
|
isActive() {
|
||||||
return (panel) => this.layout.indexOf(panel.id) > -1
|
return (panel) => this.layout.indexOf(panel.id) > -1
|
||||||
|
@ -120,6 +129,20 @@ export default {
|
||||||
callbacks() {
|
callbacks() {
|
||||||
this.rerenderPanels()
|
this.rerenderPanels()
|
||||||
},
|
},
|
||||||
|
callbacksStatus() {
|
||||||
|
for (const app in this.callbacksStatus) {
|
||||||
|
const element = this.$refs['status-' + app]
|
||||||
|
if (this.statuses[app] && this.statuses[app].mounted) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (element) {
|
||||||
|
this.callbacksStatus[app](element[0])
|
||||||
|
Vue.set(this.statuses, app, { mounted: true })
|
||||||
|
} else {
|
||||||
|
console.error('Failed to register panel in the frontend as no backend data was provided for ' + app)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
|
@ -136,6 +159,12 @@ export default {
|
||||||
register(app, callback) {
|
register(app, callback) {
|
||||||
Vue.set(this.callbacks, app, callback)
|
Vue.set(this.callbacks, app, callback)
|
||||||
},
|
},
|
||||||
|
registerStatus(app, callback) {
|
||||||
|
this.registeredStatus.push(app)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
Vue.set(this.callbacksStatus, app, callback)
|
||||||
|
})
|
||||||
|
},
|
||||||
rerenderPanels() {
|
rerenderPanels() {
|
||||||
for (const app in this.callbacks) {
|
for (const app in this.callbacks) {
|
||||||
const element = this.$refs[app]
|
const element = this.$refs[app]
|
||||||
|
@ -153,7 +182,6 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
saveLayout() {
|
saveLayout() {
|
||||||
axios.post(generateUrl('/apps/dashboard/layout'), {
|
axios.post(generateUrl('/apps/dashboard/layout'), {
|
||||||
layout: this.layout.join(','),
|
layout: this.layout.join(','),
|
||||||
|
@ -190,7 +218,7 @@ export default {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
line-height: 130%;
|
line-height: 130%;
|
||||||
padding: 80px 16px 32px;
|
padding: 80px 16px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panels {
|
.panels {
|
||||||
|
@ -305,4 +333,15 @@ export default {
|
||||||
transition: transform 1s;
|
transition: transform 1s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.statuses {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -8,4 +8,5 @@ const Instance = new Dashboard({}).$mount('#app')
|
||||||
|
|
||||||
window.OCA.Dashboard = {
|
window.OCA.Dashboard = {
|
||||||
register: (app, callback) => Instance.register(app, callback),
|
register: (app, callback) => Instance.register(app, callback),
|
||||||
|
registerStatus: (app, callback) => Instance.registerStatus(app, callback),
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,10 @@
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<li>
|
<li :class="{ inline }">
|
||||||
<div id="user-status-menu-item">
|
<div id="user-status-menu-item">
|
||||||
<span
|
<span
|
||||||
|
v-if="!inline"
|
||||||
id="user-status-menu-item__header"
|
id="user-status-menu-item__header"
|
||||||
:title="displayName">
|
:title="displayName">
|
||||||
{{ displayName }}
|
{{ displayName }}
|
||||||
|
@ -71,6 +72,12 @@ export default {
|
||||||
ActionButton,
|
ActionButton,
|
||||||
SetStatusModal,
|
SetStatusModal,
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
inline: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isModalOpen: false,
|
isModalOpen: false,
|
||||||
|
@ -237,7 +244,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
#user-status-menu-item {
|
li:not(.inline) #user-status-menu-item {
|
||||||
&__header {
|
&__header {
|
||||||
display: block;
|
display: block;
|
||||||
color: var(--color-main-text);
|
color: var(--color-main-text);
|
||||||
|
@ -270,4 +277,33 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inline #user-status-menu-item__subheader {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
> button {
|
||||||
|
background-color: var(--color-main-background);
|
||||||
|
background-size: 16px;
|
||||||
|
border: 0;
|
||||||
|
border-radius: var(--border-radius-pill);
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 0.875em;
|
||||||
|
padding-left: 40px;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
background-color: var(--color-background-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-loading-small {
|
||||||
|
&::after {
|
||||||
|
left: 21px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -20,4 +20,20 @@ const app = new Vue({
|
||||||
store,
|
store,
|
||||||
}).$mount('li[data-id="user_status-menuitem"]')
|
}).$mount('li[data-id="user_status-menuitem"]')
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
if (!OCA.Dashboard) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
OCA.Dashboard.registerStatus('status', (el) => {
|
||||||
|
const Dashboard = Vue.extend(App)
|
||||||
|
return new Dashboard({
|
||||||
|
propsData: {
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
store,
|
||||||
|
}).$mount(el)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
export { app }
|
export { app }
|
||||||
|
|
Loading…
Reference in New Issue