Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
d168abb
Implement comprehensive UI improvements and bug fixes
brayStorm Jun 8, 2025
3714764
Fix mDNS display to use configuration filename instead of device name
brayStorm Jun 15, 2025
2974083
Remove .gitattributes file not needed for upstream
brayStorm Jun 16, 2025
a4bf0e7
Apply Prettier formatting
brayStorm Jun 16, 2025
091e4a7
Merge branch 'main' into ha-data-table-integration
brayStorm Jun 19, 2025
42f3264
Merge branch 'main' into ha-data-table-integration
bdraco Sep 27, 2025
9869f83
feat: Add Home Assistant data table integration with submodule
bdraco Sep 27, 2025
3ae8eb4
Merge branch 'ha-data-table-integration' from brayStorm/dashboard
bdraco Sep 27, 2025
b55f59a
merge
bdraco Sep 27, 2025
db6d0ec
merge
bdraco Sep 27, 2025
9511d65
preen
bdraco Sep 27, 2025
1571f15
merge
bdraco Sep 27, 2025
1e4c189
convert to rspack
bdraco Sep 28, 2025
8e8808e
Remove device-ips API, use address field from device data
brayStorm Nov 26, 2025
9a37ee3
Refactor to use ha-data-table directly
brayStorm Nov 26, 2025
495a62f
Fix duplicate FAB and add row divider styling
brayStorm Nov 26, 2025
79cf3ce
Add table header controls with sort/group menus, filter sidebar, and …
brayStorm Nov 26, 2025
6735135
Add inline update button, device type column, static IP indicator, an…
brayStorm Nov 30, 2025
1b88653
Fix prettier formatting
brayStorm Nov 30, 2025
74aa103
Merge origin/main
brayStorm Nov 30, 2025
00f64a5
Redesign device list to match mockup
brayStorm Nov 30, 2025
befc658
Fix status colors and editor cursor
brayStorm Nov 30, 2025
d026120
Fix manifest.json format for ESPHome compatibility
brayStorm Nov 30, 2025
cb276d1
Fix status colors and editor cursor positioning
brayStorm Nov 30, 2025
987cc20
Update header and footer to match mockup design
brayStorm Nov 30, 2025
ceb0cdf
Fix icon column width to 56px
brayStorm Nov 30, 2025
fbfdb44
Improve device icons and fix column width
brayStorm Nov 30, 2025
2f3d050
Add icon picker dialog and update styling
brayStorm Dec 1, 2025
fbd6c9a
Use simple text input for icon picker instead of ha-icon-picker
brayStorm Dec 1, 2025
70d4d4d
Add esphome-mdi-icon component to avoid ha-icon dependencies
brayStorm Dec 1, 2025
02728a3
Add optional columns for Address, Platform, Version, Comment
brayStorm Dec 1, 2025
dde0d10
Fix column visibility toggle and persistence
brayStorm Dec 1, 2025
628b233
Fix column visibility toggle to properly handle defaultHidden columns
brayStorm Dec 1, 2025
f6782df
Fix CI type checking to skip homeassistant-frontend submodule
brayStorm Dec 2, 2025
6ea865e
Add column reordering with drag-and-drop in settings dialog
brayStorm Dec 2, 2025
de12db3
Add stub for HA frontend translationMetadata.json
brayStorm Dec 2, 2025
d72b090
Restore rollup.config.mjs for web.esphome.io build
brayStorm Dec 2, 2025
6b1c465
Add rollup packages back for web.esphome.io build
brayStorm Dec 2, 2025
022a402
Fix prettier formatting in esphome-main.ts
brayStorm Dec 2, 2025
7b6b32b
Include icon column in customize modal for reordering
brayStorm Dec 2, 2025
73c2d26
Fix editor cursor and page scroll issues
brayStorm Dec 2, 2025
ba41c8d
Fix npm install: remove rollup override and windows-specific binding
brayStorm Dec 2, 2025
3e49b39
Fix editor header and menu z-index issues
brayStorm Dec 2, 2025
f773bf1
Fix rollup override causing npm install failure
brayStorm Dec 2, 2025
0d6ad49
Fix editor main container to use fixed positioning for proper Monaco …
brayStorm Dec 3, 2025
d4a55c7
Revert editor to working state and fix MDI icon loading
brayStorm Dec 3, 2025
8945799
Fix MDI icon loading with bundled common icons and CDN fallback
brayStorm Dec 3, 2025
57e5c73
Add connectedCallback to ensure icon loads on initial render
brayStorm Dec 3, 2025
4f4d5ca
Fix editor layout with explicit main height calculation
brayStorm Dec 3, 2025
082662f
Fix editor layout and add cache busting to script URLs
brayStorm Dec 3, 2025
8ed0a3c
Revert editor to original upstream version
brayStorm Dec 3, 2025
21c9a9e
Fix editor CSS conflicts with global esphome-2.css styles
brayStorm Dec 3, 2025
b652822
Fix MDI icon component to trigger re-render after CDN fetch
brayStorm Dec 3, 2025
478f821
Fix editor CSS with !important to override external stylesheet
brayStorm Dec 3, 2025
94ff3eb
Fix MDI icon path extraction regex
brayStorm Dec 3, 2025
9f39884
Fix race condition in MDI icon loading for rapid input changes
brayStorm Dec 3, 2025
d86da24
Fix editor layout to properly fill viewport and isolate from global s…
brayStorm Dec 4, 2025
733927f
Fix editor header z-index to be clickable above Monaco editor
brayStorm Dec 4, 2025
ca09cb8
Fix Monaco editor layout and scrolling issues
brayStorm Dec 4, 2025
b6bbc93
Simplify editor layout using :host selector and automaticLayout
brayStorm Dec 4, 2025
a508bd6
Restore manual editor dimension calculation like upstream
brayStorm Dec 4, 2025
5937a90
Test: revert to upstream-style CSS (no :host fixed positioning)
brayStorm Dec 4, 2025
d0a1e72
Test: restore :host CSS, revert to original .esphome-header class name
brayStorm Dec 4, 2025
0f6e05b
Revert editor to match upstream (fix :host in light DOM)
brayStorm Dec 4, 2025
2aecedc
Remove static styles from esphome-main (doesn't work in light DOM)
brayStorm Dec 4, 2025
4d480a2
Disable Monaco stickyScroll feature
brayStorm Dec 4, 2025
56f86ef
Add debug logging to calcEditorSize
brayStorm Dec 5, 2025
240f0b1
Fix Monaco editor layout with automaticLayout and fixed positioning
brayStorm Dec 6, 2025
1efc2a0
Fix Monaco editor scrolling with absolute positioning
brayStorm Dec 6, 2025
6218f16
Add Monaco editor worker support to rspack build
brayStorm Dec 8, 2025
ec3406e
Import Monaco editor CSS to fix editor styling
brayStorm Dec 8, 2025
d5b82dc
Switch build from rspack to rollup for proper Monaco bundling
brayStorm Dec 8, 2025
b7d65a2
Inject Monaco CSS into document head for proper styling
brayStorm Dec 8, 2025
d1d47a8
Fix table columns, add update button, improve action menu z-index
brayStorm Dec 8, 2025
59b62f2
Fix action event bubbling in button menu component
brayStorm Dec 8, 2025
a70fed7
Fix button menu click handling and event propagation
brayStorm Dec 8, 2025
b981842
Fix menu popup clipping with fixed positioning
brayStorm Dec 8, 2025
6882945
Fix menu positioning with absolute mode and overflow visible
brayStorm Dec 8, 2025
7eeade1
fix: use fixed positioning for button menu to escape overflow clipping
brayStorm Dec 9, 2025
fb388e8
fix: menu positioning with manual x/y coords and remove icon column t…
brayStorm Dec 9, 2025
b325f2f
fix: menu positioning, icon column label, and Monaco context menu
brayStorm Dec 9, 2025
8e102c4
refactor: switch to ha-md-button-menu for row actions
brayStorm Dec 9, 2025
a33fad6
fix: import full Monaco editor with all contributions
brayStorm Dec 9, 2025
8d6e000
Merge mockup-redesign fixes into ha-data-table-integration
brayStorm Dec 9, 2025
999a3a4
merge: resolve ci.yml conflict with upstream
brayStorm Dec 9, 2025
f1a8a9e
fix: resolve CI type check failures
brayStorm Dec 10, 2025
293752c
style: fix prettier formatting issues
brayStorm Dec 10, 2025
d20b630
fix: copy Monaco codicon font for folding icons
brayStorm Dec 12, 2025
aa00849
fix: override codicon font-face instead of replacing bundled CSS
brayStorm Dec 12, 2025
a382e46
fix: use API-only Monaco import for shims and provider
brayStorm Dec 13, 2025
cc08a25
fix: use Proxy for lazy Monaco exports to fix Chrome init
brayStorm Dec 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,23 @@ jobs:

steps:
- uses: actions/checkout@v6.0.1
with:
submodules: recursive
- name: Use Node.js
uses: actions/setup-node@v5.0.0
with:
node-version: 24
- run: npm ci
- run: tsc
- name: Type check
run: |
# Type check src files only, ignoring homeassistant-frontend submodule errors
tsc 2>&1 | grep -v "^homeassistant-frontend/" | tee /tmp/tsc-output.txt
# Fail only if there are errors in our source files
if grep -q "^src/\|^web.esphome.io/src/" /tmp/tsc-output.txt; then
echo "TypeScript errors found in source files:"
grep "^src/\|^web.esphome.io/src/" /tmp/tsc-output.txt
exit 1
fi
- run: script/build
- run: web.esphome.io/script/build_web
- run: npm exec -- prettier --check src web.esphome.io/src
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ esphome_dashboard.egg-info
dist
.vscode/settings.json
venv
deployment-notes.md
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "homeassistant-frontend"]
path = homeassistant-frontend
url = https://github.com/home-assistant/frontend.git
1 change: 1 addition & 0 deletions homeassistant-frontend
Submodule homeassistant-frontend added at c814b8
22,144 changes: 17,479 additions & 4,665 deletions package-lock.json

Large diffs are not rendered by default.

59 changes: 53 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,102 @@
"license": "Apache-2.0",
"scripts": {
"develop": "script/develop",
"build": "script/build",
"develop_web": "web.esphome.io/script/develop_web",
"prepublishOnly": "script/build"
"prepublishOnly": "npm run build"
},
"devDependencies": {
"@babel/core": "^7.28.4",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-decorators": "^7.28.0",
"@babel/plugin-transform-runtime": "^7.28.3",
"@babel/preset-env": "^7.28.3",
"@babel/preset-typescript": "^7.27.1",
"@bundle-stats/plugin-webpack-filter": "^4.21.3",
"@formatjs/intl-durationformat": "^0.7.1",
"@lit-labs/virtualizer": "^2.1.1",
"@rollup/plugin-commonjs": "^28.0.6",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.3.0",
"@rsdoctor/rspack-plugin": "^1.3.0",
"@rspack/cli": "^1.5.7",
"@rspack/core": "^1.5.7",
"@swc/helpers": "^0.5.17",
"@types/color-name": "^2.0.0",
"@vaadin/combo-box": "^24.9.1",
"@vaadin/vaadin-material-styles": "^24.9.1",
"@vaadin/vaadin-themable-mixin": "^24.9.1",
"babel-loader": "^10.0.0",
"babel-plugin-template-html-minifier": "^4.1.0",
"color-name": "^2.0.2",
"comlink": "^4.4.2",
"core-js": "^3.45.1",
"culori": "^4.0.2",
"fancy-log": "^2.0.0",
"fs-extra": "^11.3.0",
"home-assistant-js-websocket": "^9.5.0",
"monaco-editor": "^0.52.2",
"nunjucks": "^3.2.4",
"postcss": "^8.5.6",
"postcss": "^8.5.3",
"postcss-url": "^10.1.3",
"prettier": "^3.6.2",
"rollup": "^4.50.1",
"rollup-plugin-copy": "^3.5.0",
"rollup-plugin-monaco-editor": "^0.2.1",
"rollup-plugin-postcss": "^4.0.2",
"rspack-manifest-plugin": "^5.1.0",
"serve": "^14.2.5",
"typescript": "^5.8.3"
"terser-webpack-plugin": "^5.3.14",
"typescript": "^5.8.3",
"webpack-stats-plugin": "^1.1.3",
"webpackbar": "^7.0.0",
"weekstart": "^2.0.0"
},
"dependencies": {
"@babel/runtime": "^7.28.4",
"@formatjs/intl-datetimeformat": "^6.17.1",
"@formatjs/intl-displaynames": "^6.8.8",
"@formatjs/intl-getcanonicallocales": "^2.5.4",
"@formatjs/intl-listformat": "^7.7.8",
"@formatjs/intl-locale": "^4.2.8",
"@formatjs/intl-numberformat": "^8.15.1",
"@formatjs/intl-pluralrules": "^5.4.1",
"@formatjs/intl-relativetimeformat": "^11.4.8",
"@home-assistant/webawesome": "^3.0.0-beta.4.ha.3",
"@lit-labs/motion": "^1.0.8",
"@lit-labs/observers": "^2.0.6",
"@material/mwc-button": "^0.27.0",
"@material/mwc-circular-progress": "^0.27.0",
"@material/mwc-dialog": "^0.27.0",
"@material/mwc-fab": "^0.27.0",
"@material/mwc-formfield": "^0.27.0",
"@material/mwc-icon": "^0.27.0",
"@material/mwc-icon-button": "^0.27.0",
"@material/mwc-list": "^0.27.0",
"@material/mwc-menu": "^0.27.0",
"@material/mwc-radio": "^0.27.0",
"@material/mwc-select": "^0.27.0",
"@material/mwc-snackbar": "^0.27.0",
"@material/mwc-textfield": "^0.27.0",
"@material/web": "^2.4.0",
"@mdi/js": "^7.4.47",
"@polymer/paper-tooltip": "^3.0.1",
"@types/w3c-web-serial": "^1.0.8",
"deep-clone-simple": "^1.1.1",
"element-internals-polyfill": "^3.0.2",
"esptool-js": "^0.5.3",
"improv-wifi-serial-sdk": "^2.5.0",
"lit": "^2.8.0",
"memoize-one": "^6.0.0",
"sortablejs": "^1.15.6",
"tslib": "^2.8.1",
"yaml": "^2.8.1"
},
"overrides": {
"@lit/reactive-element": "1.3.2",
"rollup-plugin-monaco-editor": {
"monaco-editor": "$monaco-editor",
"rollup": "$rollup"
"monaco-editor": "$monaco-editor"
}
}
}
2 changes: 1 addition & 1 deletion raw_package/index.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

{% block footer %}
<script
src="{{ get_static_file_url('js/esphome/index.js') }}"
src="{{ get_static_file_url('js/esphome/index.js') }}?v={{ version }}"
type="module"
></script>
{% end %}
Expand Down
8 changes: 5 additions & 3 deletions raw_package/static/css/esphome-2.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
:root {
/* Colors */
--primary-bg-color: #fafafa;
--primary-background-color: #fafafa;
--primary-footer-bg-color: #212121;
--card-background-color: #fafafa;
--alert-standard-color: #666666;
Expand All @@ -17,7 +18,7 @@
--alert-error-color-bg: #faefeb;
--mdc-theme-primary: #03a9f4;
--primary-text-color: #212121;
--mdc-dialog-z-index: 998;
--mdc-dialog-z-index: 10000;
--mdc-theme-primary-no-attention: #444444;
--mdc-theme-on-primary-no-attention: white;
--esphome-background-header: #e0e0e0;
Expand All @@ -33,7 +34,8 @@
/* dark theme */
@media (prefers-color-scheme: dark) {
:root {
--primary-bg-color: #000000;
--primary-bg-color: #111111;
--primary-background-color: #111111;
--primary-text-color: #e1e1e1;
--primary-footer-bg-color: #101e24;
--esphome-background-header: #282828;
Expand Down Expand Up @@ -103,7 +105,7 @@ esphome-main {
background-color: var(--esphome-background-header);
color: var(--primary-text-color);
padding: 0 24px;
z-index: 1;
z-index: 50;
}

.flex {
Expand Down
129 changes: 129 additions & 0 deletions rspack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
const haRspack = require("./homeassistant-frontend/build-scripts/rspack.cjs");
const haPaths = require("./homeassistant-frontend/build-scripts/paths.cjs");
const path = require("path");
const fs = require("fs");
const rspack = require("@rspack/core");

const isProdBuild = process.env.NODE_ENV === "production";

// Plugin to fix manifest.json format for ESPHome compatibility and copy Monaco worker
// ESPHome expects {"index": "index.js", "editor.worker": "..."} format
class FixManifestPlugin {
apply(compiler) {
compiler.hooks.afterEmit.tapAsync(
"FixManifestPlugin",
(compilation, callback) => {
const outputPath = compiler.options.output.path;
const manifestPath = path.resolve(outputPath, "manifest.json");

try {
// Fix the manifest format
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
const fixedManifest = {};
for (const [key, value] of Object.entries(manifest)) {
// Remove .js extension from key, extract just filename from value
const newKey = key.replace(/\.js$/, "");
const newValue = path.basename(value);
fixedManifest[newKey] = newValue;
}

// Add editor.worker entry that Monaco expects
fixedManifest["editor.worker"] =
"monaco-editor/esm/vs/editor/editor.worker.js";

fs.writeFileSync(manifestPath, JSON.stringify(fixedManifest));
} catch (e) {
console.error("FixManifestPlugin error:", e);
}

// Copy Monaco editor worker to the expected location
const monacoWorkerSrc = path.resolve(
__dirname,
"node_modules/monaco-editor/esm/vs/editor/editor.worker.js",
);
const monacoWorkerDest = path.resolve(
outputPath,
"monaco-editor/esm/vs/editor/editor.worker.js",
);

try {
fs.mkdirSync(path.dirname(monacoWorkerDest), { recursive: true });
fs.copyFileSync(monacoWorkerSrc, monacoWorkerDest);
} catch (e) {
console.error("Failed to copy Monaco worker:", e);
}

// Copy Monaco codicon font for folding icons, etc.
const codiconSrc = path.resolve(
__dirname,
"node_modules/monaco-editor/min/vs/base/browser/ui/codicons/codicon/codicon.ttf",
);
const codiconDest = path.resolve(outputPath, "codicon.ttf");

try {
fs.copyFileSync(codiconSrc, codiconDest);
} catch (e) {
console.error("Failed to copy Monaco codicon font:", e);
}

callback();
},
);
}
}

// Override paths to point to our directory structure
haPaths.polymer_dir = __dirname;

const createConfig = ({ isProdBuild, latestBuild = true }) => {
// Use the HA frontend's rspack configuration
const config = haRspack.createRspackConfig({
name: "esphome",
entry: {
index: path.resolve(__dirname, "src/index.ts"),
},
outputPath: path.resolve(__dirname, "esphome_dashboard/static/js/esphome"),
publicPath: "/static/js/esphome/",
isProdBuild,
latestBuild,
isStatsBuild: false,
isTestBuild: false,
});

// Override output to use consistent filename
config.output = {
...config.output,
filename: "[name].js",
chunkFilename: "[name].chunk.js",
};

// Override resolve to work with our setup
config.resolve = {
...config.resolve,
modules: [
"node_modules",
path.resolve(__dirname, "homeassistant-frontend/src"),
],
alias: {
...config.resolve.alias,
"@ha": path.resolve(__dirname, "homeassistant-frontend/src"),
// Stub out HA frontend build artifacts that don't exist in this project
"../../build/translations/translationMetadata.json": path.resolve(
__dirname,
"src/stubs/translationMetadata.json",
),
},
};

// No dev server needed - we build directly to esphome_dashboard/static
// The develop script uses --watch mode to rebuild on changes

// Add plugin to fix manifest format for ESPHome
config.plugins.push(new FixManifestPlugin());

return config;
};

module.exports = isProdBuild
? createConfig({ isProdBuild: true })
: createConfig({ isProdBuild: false });
10 changes: 6 additions & 4 deletions script/build
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ set -e

cd "$(dirname "$0")/.."

rm -rf esphome_dashboard
if [ ! -d "./node_modules" ]; then
echo "Directory /node_modules DOES NOT exists."
echo "Running npm install"
npm install
fi

cp -r raw_package esphome_dashboard

NODE_ENV=production npm exec -- rollup -c
NODE_ENV=production exec ./node_modules/.bin/rspack build --config rspack.config.js
13 changes: 8 additions & 5 deletions script/develop
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ set -e

cd "$(dirname "$0")/.."

rm -rf esphome_dashboard

cp -r raw_package esphome_dashboard

npm exec -- rollup -c --watch
if [ ! -d "./node_modules" ]; then
echo "Directory /node_modules DOES NOT exists."
echo "Running npm install"
npm install
fi

# Build in watch mode for development, writing directly to esphome_dashboard/static
exec ./node_modules/.bin/rspack build --watch --config rspack.config.js
Loading
Loading