# State And Component Model

This document translates current global helpers into target Vue concepts.

## Current Global To Target Mapping

| Current Global | Current Role | Target Vue Concept |
| --- | --- | --- |
| `Screens` | Hash routing, route loading/error state, reinit. | Vue Router plus route-level components and query invalidation. |
| `SmartHomeApi` | Callback API wrapper. | Promise-based API client with normalized result shape. |
| `DataProvider` | Simple raw data cache. | Pinia stores or composable query cache. |
| `FavoritesStore` | LocalStorage favorite area ids. | `useFavoritesStore` backed by localStorage. |
| `Helper.template` | HTML string factories. | Vue components and slots. |
| `Helper.states` | Button/card loading mutations. | Component props/state. |
| `Helper.unification` | Field and date normalization. | API mappers and formatting utilities. |
| `Modals` | Global modal factory. | Dialog/modal components managed by store or local state. |
| `Toasts` | Global toast factory. | Toast service/store from UI kit or app shell. |
| `confirmPopup` | Confirmation dialog. | Reusable confirm dialog service. |
| `advancedSelect` | Searchable select. | UI kit select/autocomplete component. |
| `editableString` | Inline editing. | Reusable `InlineEditableText` component. |

## Suggested Stores

### `useAreasStore`

Responsibilities:

- Load areas list.
- Build area tree.
- Cache area records by id.
- Invalidate area list after create/update/remove/place operations.

State:

- `areas`
- `areasById`
- `isLoading`
- `error`

### `useDevicesStore`

Responsibilities:

- Load devices list.
- Load live device status with per-device state.
- Mark device as offline/lost based on API response.
- Reboot/reset/remove/setup/update devices.

State:

- `devices`
- `devicesById`
- `deviceStatusById`
- `deviceStatusLoadingById`
- `deviceStatusErrorById`

### `useScriptsStore`

Responsibilities:

- Load action scripts.
- Load regular scripts.
- Load scopes.
- Run scripts.
- Enable/disable scripts and scopes.

State:

- `actions`
- `regular`
- `scopes`
- mutation loading state by alias/name.

### `useFavoritesStore`

Responsibilities:

- Persist favorite area ids to localStorage key `sh_fav_areas`.
- Provide `has`, `add`, `remove`, `toggle`, `getAll`.

Compatibility:

- Preserve current storage key to keep existing user favorites.

## Core Components

### `AppShell`

Owns:

- Header.
- Main layout.
- Global navigation.
- Toast outlet.
- Modal outlet if a global modal service is used.

### `SectionSidebar`

Props:

- `items`
- `activeRoute`

Used by:

- Devices section.
- Scripts section.
- Areas section.

### `DataTable`

Required features:

- Caption/title.
- Empty state.
- Footer/meta area.
- Cell slots.

### `DeviceState`

Props:

- `deviceId`
- `deviceType`
- `initialConnectionStatus`

Required behavior:

- If initial connection status is `lost`, show offline state and do not request
  live status.
- Otherwise load status through devices store/API.
- Show loading, error, and rendered state.
- Support manual retry.

### `ActionScriptCard`

Props:

- Script action object.

Events:

- `run`
- `details`

Required behavior:

- Loading state while running.
- Success flash when run succeeds.
- Disabled/ warning visual state when script is disabled.

### `InlineEditableText`

Props:

- `modelValue`
- `multiline`
- `validate`

Events:

- `save`
- `cancel`

Required behavior:

- Restore previous value on failed save.
- Expose loading and error state.

### `PlaceInArea`

Props:

- `targetType`: `area | device | action`
- `targetId`
- `currentAreaId`

Required behavior:

- Instance-local state only.
- Load/select areas.
- Assign and unassign target.
- Exclude self when `targetType = area`.

## Request Concurrency

Device status loading should use an explicit concurrency limiter.

Default:

- `4` concurrent live status requests.

Requirements:

- Failed requests must resolve their queue slot.
- Requests should be cancellable when route or modal is closed.
- UI should not start live status requests for known `lost` devices.

## Error Taxonomy

The API layer should classify errors as:

- `http_error` - non-2xx response.
- `api_error` - backend returned `status: false`.
- `timeout` - client timeout or aborted request due to timeout.
- `network_error` - fetch/proxy/network failure.
- `invalid_response` - response shape does not match expected contract.
- `consumer_error` - UI/component bug; log it, but never report it as network failure.
