-
Notifications
You must be signed in to change notification settings - Fork 0
Web UI
Arun K edited this page Jan 7, 2026
·
1 revision
This is a Vue 3 monorepo for Springtail, a database management platform. It contains two frontend applications and a shared UI package:
- admin-ui: Administrative interface for managing DB instances, organizations, shards, and users
- springtail: Customer-facing application for managing accounts, databases, and instances
- ui-shared: Shared components, utilities, and API client code
# Install dependencies
pnpm install
# Run a command in a specific workspace
pnpm --filter @springtail/admin-ui <command>
pnpm --filter @springtail/springtail <command>cd apps/admin-ui
# Development server (localdev mode with proxied backend)
pnpm dev
# Build for production
pnpm build
# Build for development environment
pnpm build-development
# Type check
pnpm type-check
# Run linter
pnpm lint
# Run unit tests
pnpm test:unit
# Run tests in watch mode
pnpm test:unit --watch
# Generate API types from OpenAPI spec
pnpm build-types # Requires ../../doc/openapi.jsoncd apps/springtail
# Same commands as admin-ui
pnpm dev
pnpm build
pnpm build-development
pnpm type-check
pnpm lint
pnpm test:unit
pnpm build-types # Requires ../../doc/openapi.jsoncd packages/ui-shared
# Generate API types from OpenAPI spec
pnpm build-types # Requires ../../../doc/openapi.json- Uses pnpm workspaces for dependency management
-
ui-sharedis referenced asworkspace:*in both apps - TypeScript project references configured via
tsconfig.base.json
- Vue 3 with Composition API
- Vue Router for routing
- TanStack Query (Vue Query) for server state management and caching
- Vuelidate for form validation
- Tailwind CSS for styling
- Vite for build tooling
- Vitest with jsdom for unit testing
- PropelAuth for authentication
The application uses a JSON-RPC architecture:
- RPC client in
packages/ui-shared/src/rpc.ts - All API calls go through
/jsonrpc/v1endpoint - Methods follow pattern:
namespace:Method(e.g.,dbi:GetDBInstance,user:ListUsers) - API wrapper functions in
packages/ui-shared/src/api.tsprovide typed TanStack Query hooks - Request format:
{jsonrpc: "2.0", id: number, method: string, params: object}
- API types are generated from OpenAPI spec using
openapi-typescript-codegen - Generated files live in
packages/ui-shared/src/models/api/ - DO NOT manually edit generated API types - they will be overwritten
- To regenerate types:
pnpm build-types(requires OpenAPI spec at../../doc/openapi.jsonor../../../doc/openapi.json)
- PropelAuth handles authentication
-
auth.checkLogin()verifies login and redirects to login page if needed - Router guard in
main.tschecks auth on each route transition - Access tokens are automatically added to RPC requests via Authorization header
- TanStack Query for server state (API data, caching, mutations)
- Query client configured with 5-minute stale time and retry disabled
- Mutation helpers (
acctMutate,userMutate, etc.) auto-invalidate list queries - No Pinia/Vuex - server state lives in Query cache
The ui-shared package contains reusable components in src/components/:
- dbinstance/: DB instance-specific components
- org/: Organization-specific components
- shared/: Generic UI components (Button, FormInput, FormSelect, Banner, Badge, etc.)
These components follow Tailwind CSS styling conventions and use Vuelidate for validation.
Both apps use these Vite aliases:
-
@/: Points to app'ssrc/directory -
ui-shared/: Points topackages/ui-shared/src/
Each app has environment files:
-
.env.localdev: Local development (proxied backend via Vite) -
.env.development: Development deployment -
.env.production: Production deployment
Key environment variables:
-
VITE_PROPEL_AUTH_URL: PropelAuth authentication endpoint -
VITE_API_SERVER_URL: Backend API server URL -
PROPEL_REDIRECT_URL: Post-login redirect URL
-
admin-ui: Runs on port
5174 -
springtail: Default Vite port (usually
5173) - Both use Vite proxy to forward
/jsonrpcrequests tohttp://localhost:8000in localdev mode
- Unit tests use Vitest with jsdom environment
- Tests colocated with components (same directory)
- Run tests with
pnpm test:unitorpnpm test:unit --watch
- ESLint configured with Vue 3 + TypeScript rules
- Config in
.eslintrc.cjs(per app) - Uses
@rushstack/eslint-patchfor module resolution
Use the typed API wrapper functions from ui-shared/api.ts:
import { useListDBInstances, useGetDBInstance, useCreateDBInstance } from 'ui-shared/api'
// Query hook
const { data, isLoading, error } = useListDBInstances(ref({ limit: 10 }))
// Mutation hook
const createMutation = useCreateDBInstance()
createMutation.mutate(inputData)Use Vuelidate with shared form components:
<FormInput
v-model="formData.field"
label="Field Label"
:validation="v$.field"
placeholder="Enter value"
/>- admin-ui: Routes for DB instances, organizations, shards, users
- springtail: Routes for accounts, databases, organization settings
- Both use nested routes with child views for detail pages
- Both apps share identical
main.tssetup (Vue Query, router, auth guard, click-away directive) - Generated API types should never be manually edited
- RPC client auto-handles auth tokens and 4xx error redirects
- Query invalidation is automatic for list queries after mutations
- All styling uses Tailwind CSS utility classes