Skip to content

Commit 487d17d

Browse files
Merge pull request #22357 from nextcloud/enh/dashboard/toggle-statuses
Ability to toggle statuses in dashboard
2 parents 111496c + d5edd71 commit 487d17d

10 files changed

Lines changed: 109 additions & 16 deletions

File tree

apps/dashboard/appinfo/routes.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
'routes' => [
2929
['name' => 'dashboard#index', 'url' => '/', 'verb' => 'GET'],
3030
['name' => 'dashboard#updateLayout', 'url' => '/layout', 'verb' => 'POST'],
31+
['name' => 'dashboard#updateStatuses', 'url' => '/statuses', 'verb' => 'POST'],
3132
['name' => 'dashboard#getBackground', 'url' => '/background', 'verb' => 'GET'],
3233
['name' => 'dashboard#setBackground', 'url' => '/background/{type}', 'verb' => 'POST'],
3334
]

apps/dashboard/js/dashboard.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/dashboard/js/dashboard.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/dashboard/lib/Controller/DashboardController.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,10 @@ public function index(): TemplateResponse {
103103
'url' => $widget->getUrl()
104104
];
105105
}, $this->dashboardManager->getWidgets());
106+
$configStatuses = $this->config->getUserValue($this->userId, 'dashboard', 'statuses', '{}');
107+
$statuses = json_decode($configStatuses, true);
106108
$this->inititalStateService->provideInitialState('dashboard', 'panels', $widgets);
109+
$this->inititalStateService->provideInitialState('dashboard', 'statuses', $statuses);
107110
$this->inititalStateService->provideInitialState('dashboard', 'layout', $userLayout);
108111
$this->inititalStateService->provideInitialState('dashboard', 'firstRun', $this->config->getUserValue($this->userId, 'dashboard', 'firstRun', '1') === '1');
109112
$this->inititalStateService->provideInitialState('dashboard', 'shippedBackgrounds', BackgroundService::SHIPPED_BACKGROUNDS);
@@ -131,6 +134,16 @@ public function updateLayout(string $layout): JSONResponse {
131134
return new JSONResponse(['layout' => $layout]);
132135
}
133136

137+
/**
138+
* @NoAdminRequired
139+
* @param string $statuses
140+
* @return JSONResponse
141+
*/
142+
public function updateStatuses(string $statuses): JSONResponse {
143+
$this->config->setUserValue($this->userId, 'dashboard', 'statuses', $statuses);
144+
return new JSONResponse(['statuses' => $statuses]);
145+
}
146+
134147
/**
135148
* @NoAdminRequired
136149
*/

apps/dashboard/src/App.vue

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@
3838
<Modal v-if="modal" @close="closeModal">
3939
<div class="modal__content">
4040
<h3>{{ t('dashboard', 'Edit widgets') }}</h3>
41+
<ol class="panels">
42+
<li v-for="status in sortedAllStatuses" :key="status">
43+
<input :id="'status-checkbox-' + status"
44+
type="checkbox"
45+
class="checkbox"
46+
:checked="isStatusActive(status)"
47+
@input="updateStatusCheckbox(status, $event.target.checked)">
48+
<label :for="'status-checkbox-' + status" :class="statusInfo[status].icon">
49+
{{ statusInfo[status].text }}
50+
</label>
51+
</li>
52+
</ol>
4153
<Draggable v-model="layout"
4254
class="panels"
4355
tag="ol"
@@ -90,6 +102,16 @@ const firstRun = loadState('dashboard', 'firstRun')
90102
const background = loadState('dashboard', 'background')
91103
const version = loadState('dashboard', 'version')
92104
const shippedBackgroundList = loadState('dashboard', 'shippedBackgrounds')
105+
const statusInfo = {
106+
weather: {
107+
text: t('dashboard', 'Weather'),
108+
icon: 'icon-weather-status',
109+
},
110+
status: {
111+
text: t('dashboard', 'Status'),
112+
icon: 'icon-user-status-online',
113+
},
114+
}
93115
94116
export default {
95117
name: 'App',
@@ -108,6 +130,9 @@ export default {
108130
registeredStatus: [],
109131
callbacks: {},
110132
callbacksStatus: {},
133+
allCallbacksStatus: {},
134+
statusInfo,
135+
enabledStatuses: loadState('dashboard', 'statuses'),
111136
panels,
112137
firstRun,
113138
displayName: getCurrentUser()?.displayName,
@@ -162,6 +187,12 @@ export default {
162187
isActive() {
163188
return (panel) => this.layout.indexOf(panel.id) > -1
164189
},
190+
isStatusActive() {
191+
return (status) => !(status in this.enabledStatuses) || this.enabledStatuses[status]
192+
},
193+
sortedAllStatuses() {
194+
return Object.keys(this.allCallbacksStatus).slice().sort((a, b) => a > b)
195+
},
165196
sortedPanels() {
166197
return Object.values(this.panels).sort((a, b) => {
167198
const indexA = this.layout.indexOf(a.id)
@@ -224,10 +255,15 @@ export default {
224255
Vue.set(this.callbacks, app, callback)
225256
},
226257
registerStatus(app, callback) {
227-
this.registeredStatus.push(app)
228-
this.$nextTick(() => {
229-
Vue.set(this.callbacksStatus, app, callback)
230-
})
258+
// always save callbacks in case user enables the status later
259+
Vue.set(this.allCallbacksStatus, app, callback)
260+
// register only if status is enabled or missing from config
261+
if (this.isStatusActive(app)) {
262+
this.registeredStatus.push(app)
263+
this.$nextTick(() => {
264+
Vue.set(this.callbacksStatus, app, callback)
265+
})
266+
}
231267
},
232268
rerenderPanels() {
233269
for (const app in this.callbacks) {
@@ -253,6 +289,11 @@ export default {
253289
layout: this.layout.join(','),
254290
})
255291
},
292+
saveStatuses() {
293+
axios.post(generateUrl('/apps/dashboard/statuses'), {
294+
statuses: JSON.stringify(this.enabledStatuses),
295+
})
296+
},
256297
showModal() {
257298
this.modal = true
258299
this.firstRun = false
@@ -296,6 +337,30 @@ export default {
296337
document.body.classList.remove('dashboard--dark')
297338
}
298339
},
340+
updateStatusCheckbox(app, checked) {
341+
if (checked) {
342+
this.enableStatus(app)
343+
} else {
344+
this.disableStatus(app)
345+
}
346+
},
347+
enableStatus(app) {
348+
this.enabledStatuses[app] = true
349+
this.registerStatus(app, this.allCallbacksStatus[app])
350+
this.saveStatuses()
351+
},
352+
disableStatus(app) {
353+
this.enabledStatuses[app] = false
354+
const i = this.registeredStatus.findIndex((s) => s === app)
355+
if (i !== -1) {
356+
this.registeredStatus.splice(i, 1)
357+
Vue.set(this.statuses, app, { mounted: false })
358+
this.$nextTick(() => {
359+
Vue.delete(this.callbacksStatus, app)
360+
})
361+
}
362+
this.saveStatuses()
363+
},
299364
},
300365
}
301366
</script>

apps/dashboard/src/components/BackgroundSettings.vue

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,12 @@ export default {
142142
143143
.background {
144144
width: 176px;
145-
height: 96px;
146-
margin: 8px;
147-
background-size: cover;
148-
background-position: center center;
145+
height: 96px;
146+
margin: 8px;
147+
background-size: cover;
148+
background-position: center center;
149149
text-align: center;
150-
border-radius: var(--border-radius-large);
150+
border-radius: var(--border-radius-large);
151151
border: 2px solid var(--color-main-background);
152152
overflow: hidden;
153153
@@ -166,8 +166,8 @@ export default {
166166
167167
&.active,
168168
&:hover,
169-
&:focus {
170-
border: 2px solid var(--color-primary);
169+
&:focus {
170+
border: 2px solid var(--color-primary);
171171
}
172172
173173
&.active:not(.icon-loading):after {
@@ -178,6 +178,10 @@ export default {
178178
content: '';
179179
display: block;
180180
height: 100%;
181+
182+
body.theme--dark & {
183+
background-image: var(--icon-checkmark-000);
184+
}
181185
}
182186
}
183187
}

apps/user_status/css/user-status-menu.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
@include icon-color('app', 'user_status', $color-black, 1);
2525
}
2626

27+
body.theme--dark .icon-user-status {
28+
@include icon-color('app', 'user_status', $color-white, 1);
29+
}
30+
2731
.icon-user-status-away {
2832
@include icon-color('user-status-away', 'user_status', '#F4A331', 2);
2933
}

apps/weather_status/js/weather-status.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/weather_status/js/weather-status.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/weather_status/src/App.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,12 @@ export default {
360360
</script>
361361

362362
<style lang="scss">
363+
.icon-weather-status {
364+
background-image: url('./../img/app-dark.svg');
365+
}
366+
body.theme--dark .icon-weather-status {
367+
background-image: url('./../img/app.svg');
368+
}
363369
.icon-clearsky-day {
364370
background-image: url('./../img/sun.svg');
365371
}

0 commit comments

Comments
 (0)