context.tsx1.2 KBView on GitHub 'use client';
import { createContext, useContext } from 'react';
import type { DashboardRow } from '../types/dashboard';
export interface ResolvedSource {
rows: DashboardRow[];
isLoading: boolean;
error?: unknown;
}
/** Map of source name → resolved rows, provided once at the dashboard root. */
const SourcesContext = createContext<Record<string, ResolvedSource>>({});
export const SourcesProvider = SourcesContext.Provider;
export function useSources() {
return useContext(SourcesContext);
}
/**
* Repeater scope — the current row, the team aggregate to compare against, and
* the binding name used in `{{<as>.field}}` templates. Undefined outside a
* repeater.
*/
export interface RepeaterScope {
row: DashboardRow;
team: DashboardRow;
as: string;
}
const ScopeContext = createContext<RepeaterScope | null>(null);
export const ScopeProvider = ScopeContext.Provider;
export function useScope() {
return useContext(ScopeContext);
}
/** Interpolation scope object: `{ [as]: row, team, row }`. */
export function templateScope(scope: RepeaterScope | null): Record<string, unknown> {
if (!scope) return {};
return { [scope.as]: scope.row, row: scope.row, team: scope.team };
}