- Introduced new routes for Automation Rules and Automation Tasks in the frontend. - Updated the AppSidebar to include sub-items for Automation navigation. - Enhanced HeaderMetricsContext to manage credit and page metrics more effectively, ensuring proper merging and clearing of metrics. - Adjusted AppLayout and TablePageTemplate to maintain credit balance while managing page metrics.
96 lines
3.2 KiB
TypeScript
96 lines
3.2 KiB
TypeScript
import { createContext, useContext, useState, ReactNode, useRef, useCallback } from 'react';
|
|
|
|
interface HeaderMetric {
|
|
label: string;
|
|
value: string | number;
|
|
accentColor: 'blue' | 'green' | 'amber' | 'purple';
|
|
}
|
|
|
|
interface HeaderMetricsContextType {
|
|
metrics: HeaderMetric[];
|
|
setMetrics: (metrics: HeaderMetric[]) => void;
|
|
clearMetrics: () => void;
|
|
}
|
|
|
|
const HeaderMetricsContext = createContext<HeaderMetricsContextType | undefined>(undefined);
|
|
|
|
export const useHeaderMetrics = () => {
|
|
const context = useContext(HeaderMetricsContext);
|
|
if (!context) {
|
|
throw new Error('useHeaderMetrics must be used within a HeaderMetricsProvider');
|
|
}
|
|
return context;
|
|
};
|
|
|
|
interface HeaderMetricsProviderProps {
|
|
children: ReactNode;
|
|
}
|
|
|
|
export const HeaderMetricsProvider: React.FC<HeaderMetricsProviderProps> = ({ children }) => {
|
|
const [metrics, setMetrics] = useState<HeaderMetric[]>([]);
|
|
const creditMetricRef = useRef<HeaderMetric | null>(null);
|
|
const pageMetricsRef = useRef<HeaderMetric[]>([]);
|
|
|
|
// Update combined metrics (credit + page metrics)
|
|
const updateCombinedMetrics = useCallback(() => {
|
|
const combined: HeaderMetric[] = [];
|
|
|
|
// Add credit balance first if it exists
|
|
if (creditMetricRef.current) {
|
|
combined.push(creditMetricRef.current);
|
|
}
|
|
|
|
// Add page metrics (filter out any credit metric to avoid duplicates)
|
|
const pageMetricsFiltered = pageMetricsRef.current.filter(
|
|
m => m.label.toLowerCase() !== 'credits'
|
|
);
|
|
combined.push(...pageMetricsFiltered);
|
|
|
|
setMetrics(combined);
|
|
}, []);
|
|
|
|
// Track last setter to distinguish between AppLayout and TablePageTemplate
|
|
const lastSetterRef = useRef<'credit' | 'page' | null>(null);
|
|
|
|
// Handle setMetrics - determine if it's credit balance or page metrics
|
|
const handleSetMetrics = useCallback((newMetrics: HeaderMetric[]) => {
|
|
// Check if this is a credit metric (single metric with label "Credits")
|
|
const creditMetric = newMetrics.find(m => m.label.toLowerCase() === 'credits');
|
|
|
|
if (newMetrics.length === 0) {
|
|
// Empty array - use last setter to determine what to clear
|
|
if (lastSetterRef.current === 'credit') {
|
|
// AppLayout is clearing credit balance
|
|
creditMetricRef.current = null;
|
|
} else {
|
|
// TablePageTemplate is clearing page metrics
|
|
pageMetricsRef.current = [];
|
|
}
|
|
updateCombinedMetrics();
|
|
} else if (creditMetric && newMetrics.length === 1) {
|
|
// This is just credit balance - update credit ref
|
|
creditMetricRef.current = creditMetric;
|
|
lastSetterRef.current = 'credit';
|
|
updateCombinedMetrics();
|
|
} else {
|
|
// This is page metrics - update page metrics ref (filter out credits)
|
|
pageMetricsRef.current = newMetrics.filter(m => m.label.toLowerCase() !== 'credits');
|
|
lastSetterRef.current = 'page';
|
|
updateCombinedMetrics();
|
|
}
|
|
}, [updateCombinedMetrics]);
|
|
|
|
const clearMetrics = useCallback(() => {
|
|
setMetrics([]);
|
|
pageMetricsRef.current = [];
|
|
creditMetricRef.current = null;
|
|
}, []);
|
|
|
|
return (
|
|
<HeaderMetricsContext.Provider value={{ metrics, setMetrics: handleSetMetrics, clearMetrics }}>
|
|
{children}
|
|
</HeaderMetricsContext.Provider>
|
|
);
|
|
};
|
|
|