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>
|
||||
<div id="app-dashboard">
|
||||
<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">
|
||||
<div v-for="panelId in layout" :key="panels[panelId].id" class="panel">
|
||||
|
@ -73,7 +79,9 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
timer: new Date(),
|
||||
registeredStatus: [],
|
||||
callbacks: {},
|
||||
callbacksStatus: {},
|
||||
panels,
|
||||
firstRun,
|
||||
displayName: getCurrentUser()?.displayName,
|
||||
|
@ -81,6 +89,7 @@ export default {
|
|||
layout: loadState('dashboard', 'layout').filter((panelId) => panels[panelId]),
|
||||
modal: false,
|
||||
appStoreUrl: generateUrl('/settings/apps'),
|
||||
statuses: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -89,18 +98,18 @@ export default {
|
|||
const shouldShowName = this.displayName && this.uid !== this.displayName
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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() {
|
||||
return (panel) => this.layout.indexOf(panel.id) > -1
|
||||
|
@ -120,6 +129,20 @@ export default {
|
|||
callbacks() {
|
||||
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() {
|
||||
setInterval(() => {
|
||||
|
@ -136,6 +159,12 @@ export default {
|
|||
register(app, callback) {
|
||||
Vue.set(this.callbacks, app, callback)
|
||||
},
|
||||
registerStatus(app, callback) {
|
||||
this.registeredStatus.push(app)
|
||||
this.$nextTick(() => {
|
||||
Vue.set(this.callbacksStatus, app, callback)
|
||||
})
|
||||
},
|
||||
rerenderPanels() {
|
||||
for (const app in this.callbacks) {
|
||||
const element = this.$refs[app]
|
||||
|
@ -153,7 +182,6 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
saveLayout() {
|
||||
axios.post(generateUrl('/apps/dashboard/layout'), {
|
||||
layout: this.layout.join(','),
|
||||
|
@ -190,7 +218,7 @@ export default {
|
|||
text-align: center;
|
||||
font-size: 32px;
|
||||
line-height: 130%;
|
||||
padding: 80px 16px 32px;
|
||||
padding: 80px 16px 0px;
|
||||
}
|
||||
|
||||
.panels {
|
||||
|
@ -305,4 +333,15 @@ export default {
|
|||
transition: transform 1s;
|
||||
}
|
||||
|
||||
.statuses {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
margin-bottom: 40px;
|
||||
|
||||
& > div {
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -8,4 +8,5 @@ const Instance = new Dashboard({}).$mount('#app')
|
|||
|
||||
window.OCA.Dashboard = {
|
||||
register: (app, callback) => Instance.register(app, callback),
|
||||
registerStatus: (app, callback) => Instance.registerStatus(app, callback),
|
||||
}
|
||||
|
|
|
@ -20,9 +20,10 @@
|
|||
-->
|
||||
|
||||
<template>
|
||||
<li>
|
||||
<li :class="{ inline }">
|
||||
<div id="user-status-menu-item">
|
||||
<span
|
||||
v-if="!inline"
|
||||
id="user-status-menu-item__header"
|
||||
:title="displayName">
|
||||
{{ displayName }}
|
||||
|
@ -71,6 +72,12 @@ export default {
|
|||
ActionButton,
|
||||
SetStatusModal,
|
||||
},
|
||||
props: {
|
||||
inline: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isModalOpen: false,
|
||||
|
@ -237,7 +244,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
#user-status-menu-item {
|
||||
li:not(.inline) #user-status-menu-item {
|
||||
&__header {
|
||||
display: block;
|
||||
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>
|
||||
|
|
|
@ -20,4 +20,20 @@ const app = new Vue({
|
|||
store,
|
||||
}).$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 }
|
||||
|
|
Loading…
Reference in New Issue