Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
347 changes: 347 additions & 0 deletions apps/dashboard/public/data/flowmemory-dashboard-v0.json

Large diffs are not rendered by default.

55 changes: 55 additions & 0 deletions apps/dashboard/src/data/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,59 @@ export interface Provenance {
localPathHint?: string;
}

export type FlowPulseContractTypeName =
| "ROOTFIELD_REGISTERED"
| "ROOT_COMMITTED"
| "ROOTFIELD_STATUS_CHANGED"
| "UNKNOWN_FLOWPULSE_TYPE";

export interface FlowPulseContractEvent {
schema: "flowmemory.flowpulse_contract_event.v0";
interfaceName: "IFlowPulse";
eventName: "FlowPulse";
eventSignatureText: string;
eventTopic0: string;
expectedTopic0: string;
topicMatchesContract: boolean;
sourceContract: string;
pulseTypeId: string;
pulseTypeName: FlowPulseContractTypeName;
indexed: {
pulseId: string;
rootfieldId: string;
actor: string;
};
payload: {
subject: string;
commitment: string;
parentPulseId: string;
sequence: string;
occurredAt: string;
uri: string;
};
receiptLocator: {
chainId: string;
blockNumber: string;
blockHash: string;
txHash: string;
transactionIndex: string;
logIndex: string;
receiptStatus: string;
};
receiptDerivedFields: string[];
}

export interface FlowPulseContractEventRef {
signalId: string;
eventName: "FlowPulse";
eventTopic0: string;
sourceContract: string;
pulseTypeId: string;
pulseTypeName: FlowPulseContractTypeName;
txHash: string;
logIndex: string;
}

export interface ProvenancedRecord {
id: string;
status: DashboardStatus;
Expand Down Expand Up @@ -149,6 +202,7 @@ export interface RootflowTransition extends ProvenancedRecord {
txHash: string;
sequence: string;
reasonCodes: string[];
contractEventRef: FlowPulseContractEventRef;
}

export interface MemorySignal extends ProvenancedRecord {
Expand All @@ -172,6 +226,7 @@ export interface MemorySignal extends ProvenancedRecord {
occurredAt: string;
uri: string;
summary: string;
contractEvent: FlowPulseContractEvent;
}

export interface MemoryReceipt extends ProvenancedRecord {
Expand Down
168 changes: 167 additions & 1 deletion apps/dashboard/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,72 @@ small {
gap: 10px;
}

.flowmemory-hero {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(280px, 0.34fr);
gap: 14px;
align-items: stretch;
border: 1px solid var(--line);
border-radius: 8px;
background: linear-gradient(135deg, #fbfcf8 0%, #edf4ef 100%);
box-shadow: var(--shadow);
}

.flowmemory-hero-main {
display: grid;
gap: 12px;
padding: 18px;
}

.flowmemory-hero-main h2 {
max-width: 780px;
margin: 0;
font-size: 1.48rem;
line-height: 1.14;
}

.flowmemory-hero-main p {
max-width: 82ch;
margin: 0;
color: #465047;
line-height: 1.5;
}

.flowmemory-spine {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 8px;
}

.flowmemory-spine span {
min-height: 34px;
padding: 8px 9px;
color: #284238;
border: 1px solid #bfd1c7;
border-radius: 7px;
background: rgba(251, 252, 248, 0.78);
font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
font-size: 0.74rem;
text-align: center;
}

.flowmemory-hero-side {
display: grid;
gap: 1px;
min-width: 0;
padding: 1px;
border-left: 1px solid var(--line);
}

.flowmemory-hero-side div {
display: grid;
gap: 5px;
align-content: center;
min-width: 0;
padding: 12px;
background: rgba(251, 252, 248, 0.72);
}

.metric-tile,
.panel,
.table-panel,
Expand Down Expand Up @@ -367,6 +433,10 @@ small {
grid-column: span 1;
}

.panel-side-bottom {
grid-column: 2;
}

.panel-heading {
display: flex;
align-items: center;
Expand Down Expand Up @@ -403,6 +473,28 @@ small {
display: grid;
}

.status-strip {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 10px 0 2px;
}

.status-strip span {
display: inline-flex;
gap: 6px;
align-items: center;
padding: 3px 6px 3px 3px;
border: 1px solid var(--line);
border-radius: 999px;
background: #f8f9f4;
}

.status-strip strong {
font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
font-size: 0.74rem;
}

.record-row {
display: grid;
grid-template-columns: minmax(0, 1fr) 270px;
Expand Down Expand Up @@ -432,7 +524,7 @@ small {
}

.record-facts {
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-template-columns: repeat(2, minmax(0, 1fr));
}

.record-facts div,
Expand Down Expand Up @@ -473,6 +565,63 @@ dd {
overflow-wrap: anywhere;
}

.contract-event-list {
display: grid;
}

.contract-event-list article {
display: grid;
gap: 9px;
padding: 12px 0;
border-bottom: 1px solid var(--line);
}

.contract-event-list article:last-child {
border-bottom: 0;
}

.contract-event-list article > div {
display: flex;
gap: 8px;
align-items: center;
min-width: 0;
}

.contract-event-list strong {
overflow-wrap: anywhere;
font-size: 0.84rem;
}

.contract-event-list dl {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 8px;
margin: 0;
}

.bundle-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 10px;
padding-top: 14px;
}

.bundle-grid article {
display: grid;
gap: 8px;
min-width: 0;
padding: 12px;
border: 1px solid var(--line);
border-radius: 7px;
background: #f7f8f4;
}

.bundle-grid strong,
.bundle-grid small {
display: block;
overflow-wrap: anywhere;
}

.block-strip {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
Expand Down Expand Up @@ -825,6 +974,23 @@ dd {
.lane-grid {
grid-template-columns: 1fr;
}

.flowmemory-hero,
.flowmemory-spine,
.contract-event-list dl,
.bundle-grid {
grid-template-columns: 1fr;
}

.flowmemory-hero-side,
.panel-side-bottom {
grid-column: auto;
}

.flowmemory-hero-side {
border-left: 0;
border-top: 1px solid var(--line);
}
}

@media (max-width: 860px) {
Expand Down
3 changes: 3 additions & 0 deletions apps/dashboard/src/test/dashboardData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ describe("dashboard fixture", () => {
expect(data.metadata.mode).toBe("fixture");
expect(data.flowPulseObservations.length).toBeGreaterThan(0);
expect(data.verifierReports.length).toBeGreaterThan(0);
expect(data.memorySignals.every((signal) => signal.contractEvent.eventName === "FlowPulse")).toBe(true);
expect(data.memorySignals.every((signal) => signal.contractEvent.topicMatchesContract)).toBe(true);
expect(data.rootflowTransitions.every((transition) => transition.contractEventRef.signalId === transition.memorySignalId)).toBe(true);
});

it("covers every required dashboard status", () => {
Expand Down
Loading
Loading