Screens Specification
App Shell
The new client should provide:
- Persistent top header with app name and global actions.
- Section navigation for Devices, Scripts, and Areas.
- Route-level loading, error, and empty states.
- Toast notifications.
- Confirmation dialogs.
- Reusable modal/dialog system.
Initial route:
/ redirects to /areas/favorites.
Devices List
Route:
Data:
GET /api/v1/devices/list
- Per active row:
GET /api/v1/devices/id/{id}/status
Table columns:
- Device name
- Connection status
- Live state
- IP
- Actions
Required behavior:
- Render DB list first.
- Load live state independently per device.
- Skip live status request for devices with
connection_status = lost.
- Limit concurrent status requests.
- Show per-row loading.
- Show per-row offline/error state.
- Provide Details action.
- Provide Reboot action with confirmation or clear feedback.
Devices Scanning
Route:
Data:
GET /api/v1/devices/scanning/all
Table columns:
- Device ID
- Device name
- Type
- Status
- IP
- MAC
- WiFi signal
- Actions
Required behavior:
- Show setup button only for devices in
setup status.
- Setup flow should collect alias, name, and description.
- On successful setup, refresh list and show success toast.
Device Setup Modal
Opened from:
Source data:
- Scanned device object from
/api/v1/devices/scanning/all.
Read-only device fields:
- All public fields returned by
/about after current field unification.
- Typical fields:
device_id, name, type, status, ip, mac, wifi_signal, firmware/core fields.
Form fields:
alias - required.
name - required.
description - optional textarea.
Submit endpoint:
POST /api/v1/devices/setup/new-device
Payload:
{
"device_ip": "192.168.2.42",
"alias": "kitchen_relay",
"name": "Kitchen relay",
"description": "Optional description"
}
Validation:
- Client-side required validation for
alias and name.
- Server-side
failed_fields should mark matching form fields.
- Server-side
msg should be shown in an inline alert.
Success behavior:
- Close modal.
- Refresh current screen data.
- Show success toast.
Scripts Actions
Route:
Data:
GET /api/v1/scripts/actions/list
POST /api/v1/scripts/actions/run
Required behavior:
- Render scripts as action cards.
- Card shows icon, name, description, and enabled/disabled visual state.
- Clicking card content runs script.
- Details action opens script details.
- Show in-progress state per card.
- Show success/failure toast.
- Refresh after successful run if current backend behavior requires it.
Scripts Regular
Route:
Data:
GET /api/v1/scripts/regular/list
GET /api/v1/scripts/regular/alias/{alias}/enable
GET /api/v1/scripts/regular/alias/{alias}/disable
Required behavior:
- Table with alias, name, filename/path, state, actions.
- Enable/disable button based on current state.
- Show in-progress state per button.
- Refresh after state mutation.
Scripts Scopes
Route:
Data:
GET /api/v1/scripts/scopes/list
GET /api/v1/scripts/scopes/name/{name}/enable
GET /api/v1/scripts/scopes/name/{name}/disable
Required behavior:
- Table with scope name, filename/path, state, actions.
- Enable/disable button based on current state.
- Show in-progress state per button.
- Refresh after state mutation.
Areas Tree
Route:
Data:
Required behavior:
- Build tree from flat list using
parent_id.
- Protect against self-reference and cycles.
- Root nodes are areas without valid parent.
- Render children collapsible by branch.
- Area row actions:
- Actions
- Devices
- Details
- Favorite toggle
- Create area button opens create modal.
Areas Favorites
Route:
Data:
GET /api/v1/areas/list
- Local favorites store.
Required behavior:
- Render only favorite areas.
- Empty state when no favorites.
- Area row actions:
- Actions
- Devices
- Remove from favorites
Favorite persistence:
- Current client uses local storage through
FavoritesStore.
- New client should preserve local-only favorite behavior unless backend support is added.
Area Devices Modal
Opened from:
- Areas tree.
- Areas favorites.
Data:
GET /api/v1/areas/id/{area_id}/devices
- Device status endpoints per device.
GET /api/v1/devices/id/{id}/reboot
GET /api/v1/areas/id/{area_id}/reboot_devices
Required behavior:
- Table with device, connection status, live state, actions.
- Reuse the same robust state-loading behavior as Devices List.
- Reboot one device.
- Reboot all devices in the area.
- Hide reboot-all if area has no devices.
- Details action opens Device Details Modal.
Device Details Modal
Opened from:
- Devices List.
- Area Devices Modal.
Source data:
- Device object from list or area-device response.
Displayed fields:
- All available device fields as key/value rows.
- Format
ip, mac, and device_id as code values.
- Format
status and connection_status as badges.
- Format
last_contact, create_at, and update_at as human-readable dates.
- Render live state through the shared Device State component.
Editable fields:
name through POST /api/v1/devices/update-name
description through POST /api/v1/devices/update-description
alias through POST /api/v1/devices/update-alias
Edit behavior:
- Use inline editable text controls.
- On successful edit, invalidate cached device data and refresh affected views.
- On failure, restore the original value and show an error toast.
Actions:
- Close.
- ReSetup through
POST /api/v1/devices/resetup.
- Reboot through
GET /api/v1/devices/id/{id}/reboot.
- Reset through
POST /api/v1/devices/reset.
- Remove through
GET /api/v1/devices/id/{id}/remove.
Dangerous actions:
- ReSetup, Reset, and Remove require confirmation.
- Remove should close modal, refresh current screen, and show success/error toast.
Placement:
- Include Place In Area component for device area assignment.
Area Actions Modal
Opened from:
- Areas tree.
- Areas favorites.
Data:
GET /api/v1/areas/id/{area_id}/scripts
- Script action run endpoint.
Required behavior:
- Show scripts/actions assigned to the area.
- Allow running action scripts.
- Show empty state when no scripts exist.
Area Details Modal
Opened from:
Required behavior:
- Show area id, display name, alias, type, parent.
- Allow editing fields covered by backend endpoints.
- Allow unassigning/moving where current backend supports it.
Displayed fields:
- All available area fields as key/value rows.
- Format
alias with link icon.
- Format
create_at and update_at.
- Render unsupported
schema as muted placeholder.
Editable fields:
display_name through POST /api/v1/areas/update-display-name
alias through POST /api/v1/areas/update-alias
Actions:
- Close.
- Remove through
GET /api/v1/areas/id/{area_id}/remove.
Dangerous actions:
- Remove requires confirmation.
- On success, invalidate area data, close modal, refresh current screen, and show success toast.
Placement:
- Include Place In Area component for changing
parent_id.
Create Area Modal
Opened from:
Form fields:
type - required.
alias - required.
display_name - required.
Supporting data:
GET /api/v1/areas/types/list
Submit endpoint:
POST /api/v1/areas/new-area
Payload:
{
"type": "room",
"alias": "office",
"display_name": "Office"
}
Required behavior:
- Load area types and provide searchable/selectable type input.
- Validate all fields as non-empty.
- Mark fields listed in server
failed_fields.
- Show server
msg in inline alert.
- On success, close modal, invalidate areas list, refresh screen, and show toast.
Action Script Details Modal
Opened from:
- Scripts Actions screen.
- Area Actions Modal where script details are available.
Displayed fields:
- Alias.
- Description.
- State badge.
- Filename.
- Author.
- PHP code block with syntax highlighting.
Actions:
- Close.
- Enable/disable action script through
action_enable or action_disable.
- Run action script through
POST /api/v1/scripts/actions/run.
Placement:
- If script has
area_id, include Place In Area component with type action.
Success behavior:
- Enable/disable closes modal, refreshes screen, and shows toast.
- Run shows button loading state; on success, closes modal and shows toast.
Place In Area Component
Used by:
- Device Details Modal.
- Area Details Modal.
- Action Script Details Modal.
Target types:
device uses /api/v1/devices/place-in-area and /api/v1/devices/id/{id}/unassign-from-area.
area uses /api/v1/areas/place-in-area and /api/v1/areas/id/{id}/unassign-from-area.
action uses /api/v1/scripts/place-in-area and /api/v1/scripts/id/{id}/unassign-from-area.
Required behavior:
- Load areas list.
- Show current parent area display name, or
Area ID {id} fallback.
- Hide unassign button when current parent id is
0.
- Show searchable area selector.
- Exclude self from candidate list when target type is
area.
- On assignment success, update current parent, invalidate areas data, refresh relevant views, and show success toast.
- On unassign success, set current parent to
0, invalidate areas data, refresh relevant views, and show success toast.
Implementation note:
- Current client stores component state in module-level variables, so multiple instances can conflict. The Vue implementation must keep each Place In Area instance state-isolated.