Build dashboards you can actually look at and press
Widgets bind to a message name and read it live off the socket the editor already had — lifted out of the flow editor so a dashboard route gets the same values, which also gives the home page live data for free. The input widgets close the loop the other way: a slider publishes into the graph and whatever consumes that message runs. Verified end to end in the running app — moving a slider set a flow input, and the stat bound to what the flow computed from it followed. View mode is plain CSS grid. A wall panel that only displays should not download the code that lets someone drag things around, and it now does not. Editing is a widget picker, a per-widget width control and a settings card fed by the message catalog. No new dependencies: the slider is a range input, the gauge is an arc, and the markdown is a five-line subset. Charts are the one widget still missing — they need a charting library and the chart tokens the design guidelines reserved — so they are stored and validated but not offered. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011LF61rxW1FG5YCD2J9YqjY
This commit is contained in:
@@ -19,7 +19,9 @@ import { Route as LayoutIndexRouteImport } from './routes/_layout/index'
|
||||
import { Route as OauthAuthorizeRouteImport } from './routes/oauth.authorize'
|
||||
import { Route as LayoutSettingsRouteImport } from './routes/_layout/settings'
|
||||
import { Route as LayoutAdminRouteImport } from './routes/_layout/admin'
|
||||
import { Route as LayoutDashboardsIndexRouteImport } from './routes/_layout/dashboards/index'
|
||||
import { Route as CanvasFlowsIndexRouteImport } from './routes/_canvas/flows/index'
|
||||
import { Route as LayoutDashboardsNameRouteImport } from './routes/_layout/dashboards/$name'
|
||||
import { Route as CanvasFlowsFlowNameRouteImport } from './routes/_canvas/flows/$flowName'
|
||||
|
||||
const SignupRoute = SignupRouteImport.update({
|
||||
@@ -70,11 +72,21 @@ const LayoutAdminRoute = LayoutAdminRouteImport.update({
|
||||
path: '/admin',
|
||||
getParentRoute: () => LayoutRoute,
|
||||
} as any)
|
||||
const LayoutDashboardsIndexRoute = LayoutDashboardsIndexRouteImport.update({
|
||||
id: '/dashboards/',
|
||||
path: '/dashboards/',
|
||||
getParentRoute: () => LayoutRoute,
|
||||
} as any)
|
||||
const CanvasFlowsIndexRoute = CanvasFlowsIndexRouteImport.update({
|
||||
id: '/flows/',
|
||||
path: '/flows/',
|
||||
getParentRoute: () => CanvasRoute,
|
||||
} as any)
|
||||
const LayoutDashboardsNameRoute = LayoutDashboardsNameRouteImport.update({
|
||||
id: '/dashboards/$name',
|
||||
path: '/dashboards/$name',
|
||||
getParentRoute: () => LayoutRoute,
|
||||
} as any)
|
||||
const CanvasFlowsFlowNameRoute = CanvasFlowsFlowNameRouteImport.update({
|
||||
id: '/flows/$flowName',
|
||||
path: '/flows/$flowName',
|
||||
@@ -91,7 +103,9 @@ export interface FileRoutesByFullPath {
|
||||
'/settings': typeof LayoutSettingsRoute
|
||||
'/oauth/authorize': typeof OauthAuthorizeRoute
|
||||
'/flows/$flowName': typeof CanvasFlowsFlowNameRoute
|
||||
'/dashboards/$name': typeof LayoutDashboardsNameRoute
|
||||
'/flows/': typeof CanvasFlowsIndexRoute
|
||||
'/dashboards/': typeof LayoutDashboardsIndexRoute
|
||||
}
|
||||
export interface FileRoutesByTo {
|
||||
'/': typeof LayoutIndexRoute
|
||||
@@ -103,7 +117,9 @@ export interface FileRoutesByTo {
|
||||
'/settings': typeof LayoutSettingsRoute
|
||||
'/oauth/authorize': typeof OauthAuthorizeRoute
|
||||
'/flows/$flowName': typeof CanvasFlowsFlowNameRoute
|
||||
'/dashboards/$name': typeof LayoutDashboardsNameRoute
|
||||
'/flows': typeof CanvasFlowsIndexRoute
|
||||
'/dashboards': typeof LayoutDashboardsIndexRoute
|
||||
}
|
||||
export interface FileRoutesById {
|
||||
__root__: typeof rootRouteImport
|
||||
@@ -118,7 +134,9 @@ export interface FileRoutesById {
|
||||
'/oauth/authorize': typeof OauthAuthorizeRoute
|
||||
'/_layout/': typeof LayoutIndexRoute
|
||||
'/_canvas/flows/$flowName': typeof CanvasFlowsFlowNameRoute
|
||||
'/_layout/dashboards/$name': typeof LayoutDashboardsNameRoute
|
||||
'/_canvas/flows/': typeof CanvasFlowsIndexRoute
|
||||
'/_layout/dashboards/': typeof LayoutDashboardsIndexRoute
|
||||
}
|
||||
export interface FileRouteTypes {
|
||||
fileRoutesByFullPath: FileRoutesByFullPath
|
||||
@@ -132,7 +150,9 @@ export interface FileRouteTypes {
|
||||
| '/settings'
|
||||
| '/oauth/authorize'
|
||||
| '/flows/$flowName'
|
||||
| '/dashboards/$name'
|
||||
| '/flows/'
|
||||
| '/dashboards/'
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to:
|
||||
| '/'
|
||||
@@ -144,7 +164,9 @@ export interface FileRouteTypes {
|
||||
| '/settings'
|
||||
| '/oauth/authorize'
|
||||
| '/flows/$flowName'
|
||||
| '/dashboards/$name'
|
||||
| '/flows'
|
||||
| '/dashboards'
|
||||
id:
|
||||
| '__root__'
|
||||
| '/_canvas'
|
||||
@@ -158,7 +180,9 @@ export interface FileRouteTypes {
|
||||
| '/oauth/authorize'
|
||||
| '/_layout/'
|
||||
| '/_canvas/flows/$flowName'
|
||||
| '/_layout/dashboards/$name'
|
||||
| '/_canvas/flows/'
|
||||
| '/_layout/dashboards/'
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
export interface RootRouteChildren {
|
||||
@@ -243,6 +267,13 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof LayoutAdminRouteImport
|
||||
parentRoute: typeof LayoutRoute
|
||||
}
|
||||
'/_layout/dashboards/': {
|
||||
id: '/_layout/dashboards/'
|
||||
path: '/dashboards'
|
||||
fullPath: '/dashboards/'
|
||||
preLoaderRoute: typeof LayoutDashboardsIndexRouteImport
|
||||
parentRoute: typeof LayoutRoute
|
||||
}
|
||||
'/_canvas/flows/': {
|
||||
id: '/_canvas/flows/'
|
||||
path: '/flows'
|
||||
@@ -250,6 +281,13 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof CanvasFlowsIndexRouteImport
|
||||
parentRoute: typeof CanvasRoute
|
||||
}
|
||||
'/_layout/dashboards/$name': {
|
||||
id: '/_layout/dashboards/$name'
|
||||
path: '/dashboards/$name'
|
||||
fullPath: '/dashboards/$name'
|
||||
preLoaderRoute: typeof LayoutDashboardsNameRouteImport
|
||||
parentRoute: typeof LayoutRoute
|
||||
}
|
||||
'/_canvas/flows/$flowName': {
|
||||
id: '/_canvas/flows/$flowName'
|
||||
path: '/flows/$flowName'
|
||||
@@ -277,12 +315,16 @@ interface LayoutRouteChildren {
|
||||
LayoutAdminRoute: typeof LayoutAdminRoute
|
||||
LayoutSettingsRoute: typeof LayoutSettingsRoute
|
||||
LayoutIndexRoute: typeof LayoutIndexRoute
|
||||
LayoutDashboardsNameRoute: typeof LayoutDashboardsNameRoute
|
||||
LayoutDashboardsIndexRoute: typeof LayoutDashboardsIndexRoute
|
||||
}
|
||||
|
||||
const LayoutRouteChildren: LayoutRouteChildren = {
|
||||
LayoutAdminRoute: LayoutAdminRoute,
|
||||
LayoutSettingsRoute: LayoutSettingsRoute,
|
||||
LayoutIndexRoute: LayoutIndexRoute,
|
||||
LayoutDashboardsNameRoute: LayoutDashboardsNameRoute,
|
||||
LayoutDashboardsIndexRoute: LayoutDashboardsIndexRoute,
|
||||
}
|
||||
|
||||
const LayoutRouteWithChildren =
|
||||
|
||||
Reference in New Issue
Block a user