website / docs /reference /frontend-modules.md
Andrej Janchevski
docs: add technical documentation set
175b650

Frontend modules

Module reference for src/frontend/src/. The SPA is Vue 3 + Vite + Pinia + Fomantic UI. State is held in Pinia stores; HTTP via axios; streaming inference via a fetch-based composable that parses SSE. For an overview of how the SPA fits into the deployed container, see explanation/architecture.md.

Project layout

src/frontend/src/
β”œβ”€β”€ main.js                  # bootstrap (Pinia, router, theme init)
β”œβ”€β”€ App.vue                  # shell with NavBar, RouterView, GraphBackground
β”œβ”€β”€ api/                     # axios client + per-method API wrappers
β”œβ”€β”€ composables/             # reusable logic (SSE stream)
β”œβ”€β”€ stores/                  # Pinia stores (one per demo + theme)
β”œβ”€β”€ router/                  # vue-router routes incl. SPA 404
β”œβ”€β”€ views/                   # page-level components
β”œβ”€β”€ components/              # feature-grouped components
β”œβ”€β”€ data/                    # static data (CV)
└── styles/                  # design tokens + theme + responsive CSS

main.js β€” bootstrap

Imports Fomantic CSS, design-token sheets, the App shell, the router and the theme store. Creates a Pinia instance, wires it into the app, calls useThemeStore().init() to apply the persisted theme, and mounts to #app.

api/ β€” HTTP client and endpoint wrappers

client.js

Creates the axios instance. The base URL is ${import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:8000'}/api/v1. The ?? (not ||) is load-bearing: the production env file sets VITE_API_BASE_URL= to an empty string so the SPA hits the same origin, and ?? preserves that empty string while || would have fallen back to localhost.

Also exports apiError(error) β€” pulls the structured { code, message, details } envelope back out of an axios error.

coins.js, graphGeneration.js, kgAnomaly.js, health.js

Thin wrappers around the discovery endpoints. Each function returns the parsed JSON response. The streaming endpoints are not hit through these wrappers β€” they go through useSseStream directly.

composables/useSseStream.js

The SSE client. Implements:

  • InferenceHttpError β€” typed error with status, code, details (matches the backend error envelope).
  • useSseStream({ path, body, onProgress, onPreview, onResult, signal }) β€” POSTs to ${baseURL}${path}, reads the response body as a stream, parses SSE frames, and dispatches them. Honours an AbortSignal for client-side cancellation.

The base URL is computed the same way as in client.js β€” same ?? rule applies.

This composable is the only place in the frontend that talks to the streaming endpoints. Stores instantiate it from their action functions.

stores/ β€” Pinia state

theme.js

Stores the active theme (light / dark / auto), persists it to localStorage, and toggles <html> classes on change. init() reads the persisted value at app start.

coinsDemo.js

Holds:

  • The dataset / algorithm / query-structure metadata fetched from /coins/*.
  • The user's currently selected (dataset_id, queryStructure, algorithm, anchors, variables, relations, topK).
  • loading, error, errorCode, result for the prediction call.

Getters expose selectedStructure and allowedAlgorithms (the intersection of the algorithms the dataset has and the ones that support the chosen query structure). Actions wrap the API client functions.

multiproxanDemo.js

Mirrors coinsDemo.js for the graph-generation demo. State includes the chosen model_type (discrete / continuous), sampling_mode (standard / multiprox), generation parameters, the live preview URL, the kg_log_likelihood trace (only for the kg-anomaly correction case but kept here too for future symmetry), and the continuation state blob between Gibbs rounds.

kgAnomalyDemo.js

The KG-anomaly demo state. Holds the picked sample subgraph, the user's edits, the running progress, the preview reel and the kg_log_likelihood trace.

router/index.js

Five named routes:

Path Name View
/ home HomeView.vue
/cv cv CVView.vue
/demos/coins demo-coins CoinsView.vue (lazy)
/demos/multiproxan demo-multiproxan MultiProxAnView.vue (lazy)
/demos/kganomaly demo-kganomaly KgAnomalyView.vue (lazy)
/:pathMatch(.*)* not-found NotFoundView.vue

The catch-all is the Lara Croft 404 β€” the Django backend serves the SPA shell for unknown paths and Vue Router takes it from there. meta.title is applied to document.title in router.afterEach.

views/ β€” pages

View Purpose
HomeView.vue Hero intro, demo preview cards, fact of the day, system status.
CVView.vue CV rendering driven by data/cv.js.
NotFoundView.vue Lara Croft 404 with random hero image and credits.
demos/CoinsView.vue The COINs demo (query construction, prediction results).
demos/MultiProxAnView.vue Graph-generation demo (parameter panel, preview reel, chain GIF).
demos/KgAnomalyView.vue KG-anomaly demo (subgraph picker, change list, log-likelihood plot).

components/ β€” feature groups

Components are grouped by feature folder, not by type. Cross-feature primitives live in common/ and layout/.

Folder Notable components
background/ GraphBackground.vue, FloatingMotif.vue β€” animated graph drawing background.
common/ EtaTracker.js, FitText.vue, InferenceErrorBanner.vue, PreviewReel.vue, SseProgressBar.vue, StepTimeline.vue β€” primitives used across demos.
layout/ NavBar.vue, PageSection.vue, ThemeToggle.vue.
home/ HeroIntro.vue, DemoPreviewCard.vue, FactOfTheDay.vue, SystemStatus.vue.
cv/ Education.vue, WorkExperience.vue, Publication.vue, ProjectCard.vue, Skill.vue, Language.vue, LogoOrAcronym.vue, Reference.vue, SocialLink.vue.
coins/ AlgorithmSelector.vue, QueryStructurePicker.vue, QueryGraph.vue, QueryDescription.vue, SearchableEntityDropdown.vue, SearchableRelationDropdown.vue, SearchablePicker.vue, PredictionList.vue, ResultsDashboard.vue, CommunityRankCallout.vue, TimingPanel.vue.
multiproxan/ ParametersPanel.vue β€” parameter form for both sampling modes.
kganomaly/ SampleSubgraphCard.vue, ChangeList.vue β€” subgraph picker and per-edge change explanations.

data/cv.js

A static JS module exporting the CV's structured data (education, work, publications, etc.). Updating the CV is a plain code edit β€” no DB.

styles/

File Purpose
tokens.css Design tokens (color, spacing, font sizes).
theme.css Light / dark theme variable bindings.
responsive.css Breakpoint helpers.

Build and env

  • npm run dev β€” Vite dev server on http://localhost:5173, proxied to the Django dev server at http://localhost:8000 via VITE_API_BASE_URL from .env.development.
  • npm run build β€” emits dist/ (the production bundle that the container copies into Django's dist/ so WhiteNoise serves it).
  • .env.development β€” VITE_API_BASE_URL=http://localhost:8000.
  • .env.production β€” VITE_API_BASE_URL= (empty for same-origin).

See also