Skip to content

Vue - #1007

Merged
kesselb merged 2 commits into
masterfrom
hello-vue
Jul 9, 2026
Merged

Vue#1007
kesselb merged 2 commits into
masterfrom
hello-vue

Conversation

@kesselb

@kesselb kesselb commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the ServerInfo admin settings page from a PHP-rendered template + legacy JS (Smoothie) to a Vite-built Vue 3 frontend, backed by new JSON endpoints that split static (one-time) and live (polled) data.

Changes:

  • Replaces the large templates/settings-admin.php output with a Vue mount point and loads new bundled assets from AdminSettings.
  • Adds /data (static snapshot) and updates /update (live snapshot) endpoints, with new PHP service classes (StaticData, LiveData, UptimeFormatter).
  • Introduces a new Vue UI composed of sections/components and Chart.js-based charts, plus Vite/ESLint/node tooling and REUSE license asset handling.

Reviewed changes

Copilot reviewed 47 out of 53 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
.gitignore Ignores node_modules/ for the new Node/Vite toolchain.
REUSE.toml Updates REUSE annotations to cover generated CSS assets.
appinfo/routes.php Adds /data route and keeps /update for the Vue app’s API calls.
css/main-CrF6ckF0.chunk.css Adds generated CSS bundle output.
css/serverinfo-main.css Adds CSS entrypoint that imports the generated chunk.
eslint.config.mjs Adds ESLint configuration for the new JS/Vue code.
js/script.js Removes legacy jQuery/Smoothie-based frontend code.
js/serverinfo-main.mjs.license Adds generated license metadata for the JS bundle.
js/serverinfo-main.mjs.map.license Adds generated license metadata for the source map bundle.
js/smoothie.js Removes bundled Smoothie charting library source.
lib/Controller/ApiController.php Refactors uptime formatting into UptimeFormatter.
lib/Controller/PageController.php Adds data() endpoint and updates update() to return new live payload.
lib/JobQueueInfo.php Adds Psalm API marker metadata.
lib/LiveData.php Introduces a live-data aggregator for the polling endpoint.
lib/OperatingSystems/Linux.php Enhances thermal zone discovery by reading hwmon sensors in addition to thermal zones.
lib/PhpStatistics.php Ensures stable indexed array output for PHP extensions list.
lib/Settings/AdminSettings.php Switches admin UI to load built JS/CSS bundles and returns an empty template.
lib/SlowestJobs.php Adds Psalm API marker metadata.
lib/StaticData.php Introduces a static-data aggregator for the one-time snapshot endpoint.
lib/SystemStatistics.php Makes getFreeSpace() public for reuse by StaticData.
lib/UptimeFormatter.php Extracts uptime formatting into a reusable service.
LICENSES/Apache-2.0.txt Adds third-party license text for bundle compliance.
LICENSES/GPL-3.0-or-later.txt Adds third-party license text for bundle compliance.
LICENSES/ISC.txt Adds third-party license text for bundle compliance.
LICENSES/MPL-2.0.txt Adds third-party license text for bundle compliance.
package.json Adds Vite/Vue/Chart.js dependencies, scripts, and engine constraints.
src/components/ActiveUsersSection.vue New Vue section for active-user statistics.
src/components/CpuChartSection.vue New Vue CPU chart implementation (Chart.js + vue-chartjs).
src/components/DatabaseSection.vue New Vue section for database stats.
src/components/DiskSection.vue New Vue section for disk stats with Chart.js doughnut charts.
src/components/MemoryChartSection.vue New Vue memory/swap chart implementation (Chart.js + vue-chartjs).
src/components/MonitoringSection.vue New Vue section to build the external monitoring URL interactively.
src/components/NetworkSection.vue New Vue section for network/interface information.
src/components/PhpSection.vue New Vue section for PHP/FPM statistics.
src/components/SectionSkeleton.vue New skeleton loading section shown before data loads.
src/components/SharesSection.vue New Vue section for share statistics.
src/components/SystemSection.vue New Vue section for hostname/OS/CPU/memory/time/uptime.
src/components/ThermalSection.vue New Vue section for thermal sensor data.
src/composables/useLiveData.ts Adds client polling logic for /update.
src/composables/useStaticData.ts Adds one-time fetch logic for /data.
src/main.css Adjusts styles for new icon rendering and bundled CSS behavior.
src/main.ts Adds Vue entrypoint to mount the new admin settings UI.
src/utils.ts Adds formatting and theming utilities for the Vue UI.
src/views/SettingsAdmin.vue Implements the new composed admin page layout and data wiring.
templates/settings-admin.php Replaces legacy PHP-rendered content with the Vue mount container.
tests/lib/ApiControllerTest.php Updates controller test to use UptimeFormatter dependency.
tests/lib/UptimeFormatterTest.php Adds unit tests for the new uptime formatter.
tests/psalm-baseline.xml Updates Psalm baseline for new/removed classes and new Psalm version.
vite.config.mjs Adds Vite config via @nextcloud/vite-config, including license extraction settings.
Files not reviewed (1)
  • css/main-CrF6ckF0.chunk.css: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/PhpSection.vue
Comment thread src/components/DiskSection.vue
Comment thread src/components/DiskSection.vue
Comment thread src/components/DiskSection.vue
@kesselb
kesselb requested a review from ChristophWurst June 3, 2026 19:15
@kesselb
kesselb marked this pull request as ready for review June 3, 2026 19:15
@kesselb
kesselb requested a review from benjaminfrueh as a code owner June 3, 2026 19:15
@kesselb
kesselb force-pushed the hello-vue branch 2 times, most recently from 26eae52 to 18c8df7 Compare June 4, 2026 20:23
@kesselb

kesselb commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 4, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This PR transforms the serverinfo Nextcloud app from server-side templated pages to a modern Vue 3 single-page application. The backend extracts server data collection into dedicated PHP classes (StaticData, LiveData, UptimeFormatter) that endpoints return as JSON. Controllers are refactored to use these services. The frontend introduces 14 new Vue SFC components rendering system information, thermal zones, CPU/memory charts, disk usage, network details, PHP configuration, active users, shares, and external monitoring endpoints. Two composables (useLiveData, useStaticData) handle data fetching and polling. Build infrastructure includes GitHub CI workflows, npm scripts, Vite configuration, and ESLint rules. Old JavaScript files and custom charting libraries are removed in favor of Chart.js and Vue components. Tests and tooling are updated accordingly.

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (1 warning, 2 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.36% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Vue' is vague and generic, using a single non-descriptive term that does not clearly convey the scope or purpose of the substantial changeset. Enhance the title to specifically describe the main change, such as 'Migrate admin settings to Vue' or 'Refactor serverinfo UI to Vue architecture'.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess whether the description relates to the changeset. Add a detailed description explaining the purpose, scope, and rationale for this large refactor to Vue.
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/npm-audit-fix.yml:
- Around line 42-59: The post-checkout steps run even when checkout failed; add
a guard so those steps only run on a successful checkout. Add an if condition
checking the checkout step outcome (e.g. if: ${{ steps.checkout.outcome ==
'success' }}) to the "Read package.json node and npm engines version" step (id:
versions), the "Set up node ..." step (actions/setup-node), the "Set up npm ..."
run step, and the "Fix npm audit" step (id: npm-audit) so they are skipped when
the checkout step failed.

In `@css/main-BClh5c04.chunk.css`:
- Line 1: Replace the deprecated property word-break: break-word in the source
CSS for the .infobox rule (the `@media`(width<=1280px){.infobox{...}} block) with
a modern equivalent such as overflow-wrap: anywhere (and remove the word-break
line), then rebuild the frontend assets so the generated chunk
(css/main-*.chunk.css) is regenerated without the deprecated keyword; ensure the
change is made in the source file (where .infobox is defined) not only in the
generated artifact so it persists after future builds.

In `@lib/OperatingSystems/Linux.php`:
- Around line 260-265: The enumeration only looks for temp*_label files so
temp*_input sensors without labels are ignored; update the scan to also include
temp*_input entries and create ThermalZone instances for them using a label
fallback: first glob temp*_label as before, then glob temp*_input and for each
input that wasn't already handled try to read a matching temp*_label
(str_replace('_input','_label',$inputPath)); if label exists use it, otherwise
derive a sensible type string (e.g. $name plus basename of the input file or the
temp index) and still compute $temp from readContent($inputPath)/1000 and create
new ThermalZone(md5($inputPath), $type, $temp); use readContent and ThermalZone
in the same way and maintain a set of processed input paths to avoid duplicates.

In `@src/components/CpuChartSection.vue`:
- Around line 74-76: The y-axis is hard-capped with max: 100 which clips real
overload values produced elsewhere in this component; update the y-axis options
(the object containing min, max, ticks and passiveColor()) to remove the fixed
max or replace it with a computed maximum based on the data (e.g., const
computedMax = Math.max(100, ...seriesValues) + margin) so charts auto-scale to
values >100, keep min: 0 and the ticks callback unchanged, and apply the same
change to the other y-axis config block (the similar min/max/ticks object around
the other chart setup).
- Around line 93-101: The code indexes pct[0] and load[0] without ensuring
props.cpuload has elements, causing undefined output for an empty array; update
the guard in CpuChartSection.vue to check that props.cpuload is an array with
length > 0 (e.g., Array.isArray(props.cpuload) && props.cpuload.length > 0)
before mapping/indexing, and if it's empty return the same 'CPU info not
available' (or a safe fallback) so pct and load mappings and the pct[0]/load[0]
accesses are never executed on an empty array.

In `@src/components/NetworkSection.vue`:
- Line 36: In NetworkSection.vue replace the hardcoded 'up'/'down' text with
localized strings by using the app's i18n translation method (e.g. $t or i18n.t)
instead of plain literals; update the template expression that renders iface.up
(the <span class="info">{{ iface.up ? 'up' : 'down' }}</span>) to something like
{{ iface.up ? $t('network.status.up') : $t('network.status.down') }} and ensure
corresponding keys (network.status.up, network.status.down) are present in your
locale files.

In `@src/composables/useLiveData.ts`:
- Around line 31-41: The poll() function can hang because
axios.get(generateUrl('/apps/serverinfo/update')) has no timeout; modify that
call to pass an explicit timeout (e.g.
axios.get(generateUrl('/apps/serverinfo/update'), { timeout: 5000 })) so the
request will reject on slow/hung connections and the catch/finally path (which
schedules timeoutId and increments tick.value/data.value handling) continues;
keep existing catch behavior and ensure timeoutId/stopped logic around
setTimeout(poll, 2000) remains unchanged.

In `@src/utils.ts`:
- Around line 46-55: The formatBytes function currently uses Math.abs(bytes) so
negative values lose their sign; update formatBytes to preserve the sign by
recording whether bytes is negative (e.g., const sign = bytes < 0 ? '-' : ''),
use Math.abs(bytes) for magnitude calculation with the existing units/loop
logic, and then prepend the sign to the returned string (e.g., return sign +
value.toFixed(1) + ' ' + units[i]) so negative inputs produce negative-formatted
outputs; keep the function name formatBytes and the units array unchanged.

In `@src/views/SettingsAdmin.vue`:
- Around line 139-140: The view currently only reads staticData from
useStaticData() and leaves the skeleton active when the initial fetch fails;
update the component to also read and react to the loading and error properties
returned by useStaticData() (e.g., const { data: staticData, loading:
staticLoading, error: staticError } = useStaticData()). Use staticLoading to
show the skeleton only while true, and render a clear error state/UI when
staticError is set (or show a retry button that re-invokes the fetch), ensuring
the skeleton is not permanently shown when staticData is null due to an error.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 69a56bcb-269d-4431-95fb-6838e0135a51

📥 Commits

Reviewing files that changed from the base of the PR and between 23099c4 and 18c8df7.

⛔ Files ignored due to path filters (3)
  • js/Chart.min.js is excluded by !**/*.min.js
  • js/serverinfo-main.mjs.map is excluded by !**/*.map
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (53)
  • .gitattributes
  • .github/workflows/npm-audit-fix.yml
  • .github/workflows/npm-build.yml
  • .gitignore
  • LICENSES/Apache-2.0.txt
  • LICENSES/GPL-3.0-or-later.txt
  • LICENSES/ISC.txt
  • LICENSES/MPL-2.0.txt
  • REUSE.toml
  • appinfo/routes.php
  • css/main-BClh5c04.chunk.css
  • css/serverinfo-main.css
  • eslint.config.mjs
  • js/script.js
  • js/serverinfo-main.mjs
  • js/serverinfo-main.mjs.license
  • js/serverinfo-main.mjs.map.license
  • js/smoothie.js
  • lib/Controller/ApiController.php
  • lib/Controller/PageController.php
  • lib/JobQueueInfo.php
  • lib/LiveData.php
  • lib/OperatingSystems/Linux.php
  • lib/PhpStatistics.php
  • lib/Settings/AdminSettings.php
  • lib/SlowestJobs.php
  • lib/StaticData.php
  • lib/SystemStatistics.php
  • lib/UptimeFormatter.php
  • package.json
  • src/components/ActiveUsersSection.vue
  • src/components/CpuChartSection.vue
  • src/components/DatabaseSection.vue
  • src/components/DiskSection.vue
  • src/components/MemoryChartSection.vue
  • src/components/MonitoringSection.vue
  • src/components/NetworkSection.vue
  • src/components/PhpSection.vue
  • src/components/SectionSkeleton.vue
  • src/components/SharesSection.vue
  • src/components/SystemSection.vue
  • src/components/ThermalSection.vue
  • src/composables/useLiveData.ts
  • src/composables/useStaticData.ts
  • src/main.css
  • src/main.ts
  • src/utils.ts
  • src/views/SettingsAdmin.vue
  • templates/settings-admin.php
  • tests/lib/ApiControllerTest.php
  • tests/lib/UptimeFormatterTest.php
  • tests/psalm-baseline.xml
  • vite.config.mjs
💤 Files with no reviewable changes (2)
  • js/smoothie.js
  • js/script.js

Comment thread .github/workflows/npm-audit-fix.yml
Comment thread css/main-BClh5c04.chunk.css Outdated
@@ -0,0 +1 @@
.chart-wrapper[data-v-f3151c1d],.chart-wrapper[data-v-409c36e2]{height:200px;width:100%}.section-skeleton .skeleton-bar[data-v-9a2b13f0]{background:var(--color-background-dark, #ededed);border-radius:var(--border-radius, 3px);animation:skeleton-pulse-9a2b13f0 1.5s ease-in-out infinite}.section-skeleton .skeleton-title[data-v-9a2b13f0]{height:24px;width:40%;margin-bottom:20px}.section-skeleton .skeleton-chart[data-v-9a2b13f0]{height:200px;margin-bottom:16px}@keyframes skeleton-pulse-9a2b13f0{50%{opacity:.5}}.server-info-wrapper{max-width:100vw}.monitoring-wrapper{display:-webkit-flex;display:flex;max-width:50%;min-width:50%}.monitoring-wrapper>input{flex:1 0 auto}.monitoring-wrapper+.settings-hint{margin-top:0}.rambox,.cpubox{height:10px;width:10px;background-color:var(--color-primary-element)}.swapbox{height:10px;width:10px;background-color:var(--color-background-darker)}.info{font-weight:700}.smallinfo{color:var(--color-text-maxcontrast)}.infobox{display:flex;flex-wrap:nowrap;align-items:center;padding:16px;margin:16px 0;background-color:var(--color-main-background);border:2px solid var(--color-border);border-radius:var(--border-radius-large)}.diskchart-container{width:100px;margin-right:25px;border:1px var(--color-border)}.info-color-label--available:before,.info-color-label--used:before{content:"";display:inline-block;width:10px;height:10px;border-radius:10px;margin-right:5px}.info-color-label--available:before{background-color:var(--color-border-maxcontrast)}.info-color-label--used:before{background-color:var(--color-primary-element)}@media(width<=1280px){.infobox{display:block;word-break:break-word}.text-center-mobile{text-align:center}.diskchart-container{margin:0 auto}.monitoring-wrapper{min-width:100%;max-width:100%}}.diskinfo-container{flex:1 0 auto}.infobox h3{font-weight:700;padding:5px 0 10px;margin:0}.infoicon{display:inline-flex;vertical-align:middle;margin-right:8px}.chart-container{position:relative;margin:10px}.clipboardButton{display:inline-block;position:relative;top:2px;margin-left:5px}.row{display:-webkit-flex;display:flex;flex:0 1 auto;flex-direction:row;flex-wrap:wrap;margin-left:-15px;margin-right:-15px}.col{flex-grow:1;flex-basis:0;max-width:100%;padding-left:15px;padding-right:15px}.col-1{flex-basis:8.333%;max-width:8.333%;min-width:8.333%}.col-2{flex-basis:16.666%;max-width:16.666%;min-width:16.666%}.col-3{flex-basis:25%;max-width:25%;min-width:25%}.col-4{flex-basis:33.333%;max-width:33.333%;min-width:33.333%}.col-5{flex-basis:41.666%;max-width:41.666%;min-width:41.666%}.col-6{flex-basis:50%;max-width:50%;min-width:50%}.col-7{flex-basis:58.333%;max-width:58.333%;min-width:58.333%}.col-8{flex-basis:66.666%;max-width:66.666%;min-width:66.666%}.col-9{flex-basis:75%;max-width:75%;min-width:75%}.col-10{flex-basis:83.333%;max-width:83.333%;min-width:83.333%}.col-11{flex-basis:91.666%;max-width:91.666%;min-width:91.666%}.col-12{flex-basis:100%;max-width:100%;min-width:100%}@media only screen and (max-width:1200px){.col-xl-6{flex-basis:50%;max-width:50%;min-width:50%}}@media only screen and (max-width:1024px){.col-l-6{flex-basis:50%;max-width:50%;min-width:50%}.col-l-12{flex-basis:100%;max-width:100%;min-width:100%}}@media only screen and (max-width:768px){.col-m-6{flex-basis:50%;max-width:50%;min-width:50%}.col-m-12{flex-basis:100%;max-width:100%;min-width:100%}}.monitoring-url-params{margin-top:3px;margin-bottom:3px}.monitoring-url-param{display:flex;align-items:start;margin-bottom:3px}.monitoring-url-param input{margin-top:4px;min-height:initial;height:initial}.active-users-wrapper{flex:1;display:flex;gap:0 1rem;flex-wrap:wrap;align-items:center;justify-content:center}.active-users-box{padding:.25rem 1rem;flex:1;min-width:150px;border-left:2px solid var(--color-border)}@media(width<=1280px){.active-users-box{padding:1rem .5rem;border:none;text-align:center}}.active-users-box:first-child{border:none}.active-users-box .info{font-size:2rem}.smoothie-chart-tooltip{display:flex;flex-wrap:nowrap;align-items:center;padding:16px;margin:0 .25rem;background-color:var(--color-main-background);border:2px solid var(--color-border);border-radius:var(--border-radius-large)}.server-info-table table{width:100%}.server-info-table td{padding:6px}.server-info__tag-wrapper{display:flex;flex-wrap:wrap}.server-info__php-extension-tag{display:inline-block;margin:2px;padding:1px 9px;border-radius:16px;border:1px solid var(--color-main-text)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify deprecated usage is fully removed from source and generated CSS.
rg -nP 'word-break\s*:\s*break-word' src css

Repository: nextcloud/serverinfo

Length of output: 4557


Fix remaining deprecated word-break: break-word and regenerate chunk

word-break: break-word is still present in src/main.css (line 80) and in the generated css/main-BClh5c04.chunk.css (inside @media(width<=1280px){.infobox{...}}), so the stylelint-flagged keyword hasn’t been removed from the artifact.

Source-level fix (apply in src/main.css, then rebuild assets)
 `@media` (width <= 1280px) {
 	.infobox {
 		display: block;
-		word-break: break-word;
+		overflow-wrap: anywhere;
 	}
🧰 Tools
🪛 Stylelint (17.12.0)

[error] 1-1: Deprecated keyword "break-word" for property "word-break" (declaration-property-value-keyword-no-deprecated)

(declaration-property-value-keyword-no-deprecated)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@css/main-BClh5c04.chunk.css` at line 1, Replace the deprecated property
word-break: break-word in the source CSS for the .infobox rule (the
`@media`(width<=1280px){.infobox{...}} block) with a modern equivalent such as
overflow-wrap: anywhere (and remove the word-break line), then rebuild the
frontend assets so the generated chunk (css/main-*.chunk.css) is regenerated
without the deprecated keyword; ensure the change is made in the source file
(where .infobox is defined) not only in the generated artifact so it persists
after future builds.

Comment thread lib/OperatingSystems/Linux.php
Comment thread src/components/CpuChartSection.vue
Comment thread src/components/CpuChartSection.vue
Comment thread src/components/NetworkSection.vue
Comment thread src/composables/useLiveData.ts
Comment thread src/utils.ts
Comment thread src/views/SettingsAdmin.vue

@ChristophWurst ChristophWurst left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A .nextcloudignore should be used to exclude source and package manager files from shipping, right?

@ChristophWurst

Copy link
Copy Markdown
Member

Was the second commit placed here intentionally?

@kesselb

kesselb commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator Author

A .nextcloudignore should be used to exclude source and package manager files from shipping, right?

It's not necessary, because the build script covers all cases we have here. I'm adding still, because then it's explicit what should be in the release and what not.

Was the second commit placed here intentionally?

Yes, otherwise I won't see the sensors on my device ;) It also fixes #551.

@kesselb
kesselb force-pushed the hello-vue branch 3 times, most recently from 7a0fb3c to 5ecf4c2 Compare July 8, 2026 21:11
kesselb added 2 commits July 8, 2026 23:23
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Copilot:github-copilot/gpt-5.4
Assisted-by: ClaudeCode:claude-fable-5

Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
@kesselb
kesselb merged commit 13da1ba into master Jul 9, 2026
43 checks passed
@kesselb
kesselb deleted the hello-vue branch July 9, 2026 08:52
@github-project-automation github-project-automation Bot moved this from 🏗️ In progress to ☑️ Done in 💌 📅 👥 Groupware team Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

4 participants