- Add bin-features/lib-features so cargo-leptos enables ssr/hydrate
correctly (server was exiting immediately with empty main otherwise)
- Add style-file so the CSS bundle is no longer empty
- Replace #[cfg(target_arch = "wasm32")] with #[cfg(feature = "hydrate")]
in theme.rs to match when web-sys is actually available
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The add-host form is now opened via a "+ Add host" button in the page
header. The modal closes on Cancel, backdrop click, × button, or
automatically after a successful creation.
Adds modal CSS with backdrop blur and entry animation, .btn-primary /
.btn-secondary shared button styles, and a .page-header flex layout
reusable across list pages.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements task #7. The Hosts page provides:
- Name/network/port/application filters (sentinel values instead of
Option<T> to avoid server function serialization issues)
- Configurable page size (15 default, 25/50/100/All)
- Prev/next navigation with total host count
- Add host form with network selector
- Delete action per row
Sub-components (AddHostForm, FilterBar, PaginationBar, HostTable) each
call .into_any() to erase their concrete view types. This breaks the
deeply-nested generic type that caused "queries overflow the depth
limit!" without requiring an unbounded recursion_limit increase.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds NetworkWithCounts presentation model and get_networks_with_counts()
server function using a single SQL query with correlated subqueries.
Networks table now shows host count, application count, and has the
Actions column header properly right-aligned to match the Delete button.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Home page now shows one clickable summary card per entity type
(Networks, Hosts, Applications). Each card displays the total count
fetched from the database via a single get_summary() server function,
then navigates to the corresponding page on click.
Counts are pre-rendered server-side via <Suspense> so the page is
useful even before the WASM bundle loads.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces a global design system using CSS custom properties as
design tokens. Light and dark themes are defined via [data-theme]
attribute on <html>; the system preference (prefers-color-scheme)
is the default when no explicit choice is stored.
ThemeToggle component (Auto → Light → Dark cycle) persists the
choice to localStorage and applies it on hydration without flash.
New themes can be added by defining a [data-theme="name"] CSS block
and adding a variant to ThemeChoice.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add client/networks.rs: Leptos page with ServerAction + Resource pattern
* ActionForm for CIDR creation (auto-clears after submit)
* delete button dispatches DeleteNetwork action per row
* Resource re-fetches after each create/delete via action.version()
* Suspense shows "Loading…" while Resource is pending
- Register /networks route in app.rs with temporary nav bar
- Fix db.rs: create_pool now creates the SQLite file if missing
(AnyPool has no create_if_missing option unlike SqlitePool)
- Remove redundant directory creation from main.rs (handled in db.rs)
- Fix ActionForm import: use leptos::form::ActionForm (not leptos_router)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add src/api/ module with server functions for networks, hosts, applications
- Each server function retrieves the pool via use_context::<AnyPool>()
- Pool is injected via provide_context in two places in main.rs:
* leptos_routes_with_context: for SSR renders and inline server fn calls
* handle_server_fns_with_context on /api/*fn_name: for WASM client calls
- create_host validates IP against network CIDR before inserting
- create_network validates CIDR format before inserting
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add server/repository/ module with networks, hosts, ports, applications
- Use sqlx::query() + manual row mapping (no compile-time DB required)
- Handle unique-constraint conflicts with is_unique_violation() for
cross-database compatibility (SQLite + PostgreSQL via AnyPool)
- add_port_to_host auto-registers the port in the catalog (prevents FK errors)
- application_ports has no FK to ports (intentional: loose association)
- Add DbError::NotFound variant for missing-record cases
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add sqlx 0.8 (AnyPool, runtime-tokio, sqlite, postgres, migrate)
- Create 6 migration files for both SQLite and PostgreSQL backends
- Add server/db.rs: create_pool and run_migrations helpers
- Add server/state.rs: AppState with LeptosOptions + AnyPool
- Run migrations at server startup before accepting requests
- Fix Port model: remove host_id (ports are now a global catalog)
- Add HostPort join struct for the host_ports many-to-many table
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add convention rule: all generated code and comments must follow
standard conventions and be written in English.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add shared models (Network, Host, Port, Application, ApplicationPort)
with serde derives for Leptos server function serialization.
Add server/validation.rs with valider_ip_dans_reseau() and 5 unit tests.
Gate SSR-only modules (config, validation) with #[cfg(feature = "ssr")].
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add AppConfig loaded from .env via dotenvy. DATABASE_URL prefix
determines the backend (sqlite:// → SQLite, postgresql:// → PostgreSQL).
ConfigError via thiserror gives clear messages on missing or unknown URLs.
Server logs the chosen backend at startup.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Set dist=target/site/pkg so trunk outputs WASM alongside where Axum
serves /pkg/. Disable filehash so HydrationScripts can resolve
rust-ipam.js and rust-ipam_bg.wasm without content hash suffixes.
Add data-target-name to index.html to disambiguate lib from bin target.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Shell component wrapping the full HTML document (DOCTYPE, head, body)
required by leptos_meta. Add [package.metadata.leptos] to Cargo.toml and
switch get_configuration to Some("Cargo.toml"). Server now returns valid
HTML with title injection and WASM hydration scripts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sets up the full project skeleton: Cargo.toml with ssr/hydrate features,
Axum server entry point, shared Leptos lib, root App component with router,
server/client module split, and Trunk config for WASM build.
Both `cargo check --features ssr` and `cargo check --features hydrate --target wasm32-unknown-unknown` pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>