feat(frontend): add shared layer — types, API client, router, app layout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
openclaw 2026-03-23 17:15:30 +00:00
parent c18f7c5f76
commit 7328057e7d
8 changed files with 327 additions and 0 deletions

View File

@ -0,0 +1,15 @@
<template>
<div class="app-layout">
<aside class="sidebar">
<h2>Arch Design Dashboard</h2>
<ProjectSidebar />
</aside>
<main class="content">
<router-view />
</main>
</div>
</template>
<script setup lang="ts">
import ProjectSidebar from '@/modules/project/components/ProjectSidebar.vue'
</script>

5
frontend/src/env.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}

View File

@ -0,0 +1,10 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
import './style.css'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')

View File

@ -0,0 +1,12 @@
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: () => import('@/modules/project/components/ProjectList.vue') },
{ path: '/projects/:id', component: () => import('@/modules/graph/components/GraphPanorama.vue') },
{ path: '/projects/:id/editor', component: () => import('@/modules/editor/components/EditorPage.vue') },
],
})
export default router

View File

@ -0,0 +1,3 @@
import axios from 'axios'
const api = axios.create({ baseURL: '/api' })
export default api

View File

@ -0,0 +1,198 @@
export interface Project {
id: string
name: string
design_dir: string
code_dir: string | null
created_at: string
}
export interface FileStatusEntry {
path: string
status: string
content_lines: number
}
export interface ScanSummary {
total_files: number
ok: number
sparse: number
missing: number
placeholder_heavy: number
template_residue: number
}
export interface ScanResult {
project_id: string
scanned_at: string
file_statuses: FileStatusEntry[]
summary: ScanSummary
}
export interface GraphNode {
id: string
type: string
label: string
status: string
group_id: string
}
export interface GraphEdge {
source: string
target: string
relation: string
}
export interface GraphGroup {
id: string
label: string
layer: string
}
export interface GraphView {
nodes: GraphNode[]
edges: GraphEdge[]
groups: GraphGroup[]
}
export interface Capability {
capability_id: string
name: string
description: string
priority: string
phase: string
related_value_flows: string[]
}
export interface Module {
module_id: string
name: string
layer: string
description: string
phase: string
depends_on: string[]
capabilities: string[]
}
export interface Entity {
entity_id: string
name: string
domain: string
owner_module: string
description: string
phase: string
source_file: string
}
export interface Integration {
integration_id: string
source: string
target: string
target_type: string
direction: string
protocol: string
trigger: string
phase: string
description: string
}
export interface ValueFlow {
value_flow_id: string
name: string
trigger: string
actor: string
steps: string
outcome: string
phase: string
related_capabilities: string[]
}
export interface UserJourney {
journey_id: string
name: string
actor: string
precondition: string
steps: string
postcondition: string
phase: string
related_value_flows: string[]
}
export interface DataFlow {
data_flow_id: string
source: string
target: string
data_content: string
trigger: string
protocol: string
phase: string
description: string
}
export interface ExternalSystem {
system_id: string
name: string
type: string
protocol: string
direction: string
phase: string
description: string
}
export interface TraceabilityLink {
trace_id: string
capability_id: string
module_id: string
entity_ids: string[]
value_flow_ids: string[]
notes: string
}
export interface RuntimeComponent {
component_id: string
name: string
type: string
technology: string
port: string
}
export interface EditableFile {
path: string
format: string
content: string
last_modified: string
}
export interface AffectedFile {
path: string
reason: string
}
export interface ImpactResult {
source_file: string
affected_files: AffectedFile[]
}
export interface ImplProgress {
module_id: string
percentage: number
source: string
evaluated_at: string
}
export interface CapabilityDetail {
capability: Capability
modules: Module[]
value_flows: ValueFlow[]
}
export interface ModuleDetail {
module: Module
entities: Entity[]
integrations: Integration[]
codebase_alignment: Record<string, unknown> | null
}
export interface EntityDetail {
entity: Entity
data_flows: DataFlow[]
}

83
frontend/src/style.css Normal file
View File

@ -0,0 +1,83 @@
:root {
--sidebar-width: 260px;
--color-primary: #1976D2;
--color-bg: #f5f5f5;
--color-sidebar: #fff;
--color-border: #e0e0e0;
--color-ok: #4CAF50;
--color-sparse: #FFC107;
--color-missing: #F44336;
--color-template-residue: #FF9800;
--color-placeholder-heavy: #9C27B0;
--color-unknown: #9E9E9E;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: var(--color-bg);
color: #333;
}
.app-layout {
display: grid;
grid-template-columns: var(--sidebar-width) 1fr;
min-height: 100vh;
}
.sidebar {
background: var(--color-sidebar);
border-right: 1px solid var(--color-border);
padding: 16px;
overflow-y: auto;
}
.sidebar h2 {
font-size: 16px;
margin-bottom: 16px;
color: var(--color-primary);
}
.content {
padding: 24px;
overflow-y: auto;
}
button {
cursor: pointer;
border: none;
border-radius: 4px;
padding: 8px 16px;
font-size: 14px;
}
button.primary {
background: var(--color-primary);
color: white;
}
button.danger {
background: var(--color-missing);
color: white;
}
input, textarea {
border: 1px solid var(--color-border);
border-radius: 4px;
padding: 8px;
font-size: 14px;
width: 100%;
}
.card {
background: white;
border: 1px solid var(--color-border);
border-radius: 8px;
padding: 16px;
margin-bottom: 12px;
}

1
frontend/src/vite-env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />