feat: enhance Jira analytics with caching and force refresh
- Updated `getJiraAnalytics` to accept a `forceRefresh` parameter for optional cache bypass. - Modified `getProjectAnalytics` to check the cache and return cached data unless forced to refresh. - Adjusted `loadAnalytics` in `useJiraAnalytics` to trigger a forced refresh on manual updates. - Improved UI in `JiraDashboardPageClient` to indicate when data is served from cache.
This commit is contained in:
@@ -13,7 +13,7 @@ export type JiraAnalyticsResult = {
|
||||
/**
|
||||
* Server Action pour récupérer les analytics Jira du projet configuré
|
||||
*/
|
||||
export async function getJiraAnalytics(): Promise<JiraAnalyticsResult> {
|
||||
export async function getJiraAnalytics(forceRefresh = false): Promise<JiraAnalyticsResult> {
|
||||
try {
|
||||
// Récupérer la config Jira depuis la base de données
|
||||
const jiraConfig = await userPreferencesService.getJiraConfig();
|
||||
@@ -40,8 +40,8 @@ export async function getJiraAnalytics(): Promise<JiraAnalyticsResult> {
|
||||
projectKey: jiraConfig.projectKey
|
||||
});
|
||||
|
||||
// Récupérer les analytics
|
||||
const analytics = await analyticsService.getProjectAnalytics();
|
||||
// Récupérer les analytics (avec cache ou actualisation forcée)
|
||||
const analytics = await analyticsService.getProjectAnalytics(forceRefresh);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
|
||||
98
src/actions/jira-cache.ts
Normal file
98
src/actions/jira-cache.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
'use server';
|
||||
|
||||
import { jiraAnalyticsCache } from '@/services/jira-analytics-cache';
|
||||
import { userPreferencesService } from '@/services/user-preferences';
|
||||
|
||||
export type CacheStatsResult = {
|
||||
success: boolean;
|
||||
data?: {
|
||||
totalEntries: number;
|
||||
projects: Array<{ projectKey: string; age: string; size: number }>;
|
||||
};
|
||||
error?: string;
|
||||
};
|
||||
|
||||
export type CacheActionResult = {
|
||||
success: boolean;
|
||||
message?: string;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Server Action pour récupérer les statistiques du cache
|
||||
*/
|
||||
export async function getJiraCacheStats(): Promise<CacheStatsResult> {
|
||||
try {
|
||||
const stats = jiraAnalyticsCache.getStats();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: stats
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('❌ Erreur lors de la récupération des stats du cache:', error);
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Server Action pour invalider le cache du projet configuré
|
||||
*/
|
||||
export async function invalidateJiraCache(): Promise<CacheActionResult> {
|
||||
try {
|
||||
// Récupérer la config Jira actuelle
|
||||
const jiraConfig = await userPreferencesService.getJiraConfig();
|
||||
|
||||
if (!jiraConfig.enabled || !jiraConfig.baseUrl || !jiraConfig.email || !jiraConfig.apiToken || !jiraConfig.projectKey) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'Configuration Jira incomplète'
|
||||
};
|
||||
}
|
||||
|
||||
// Invalider le cache pour ce projet
|
||||
jiraAnalyticsCache.invalidate({
|
||||
baseUrl: jiraConfig.baseUrl,
|
||||
email: jiraConfig.email,
|
||||
apiToken: jiraConfig.apiToken,
|
||||
projectKey: jiraConfig.projectKey
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `Cache invalidé pour le projet ${jiraConfig.projectKey}`
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('❌ Erreur lors de l\'invalidation du cache:', error);
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Server Action pour invalider tout le cache analytics
|
||||
*/
|
||||
export async function invalidateAllJiraCache(): Promise<CacheActionResult> {
|
||||
try {
|
||||
jiraAnalyticsCache.invalidateAll();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Tout le cache analytics a été invalidé'
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('❌ Erreur lors de l\'invalidation totale du cache:', error);
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -154,13 +154,20 @@ export function JiraDashboardPageClient({ initialJiraConfig }: JiraDashboardPage
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
onClick={refreshAnalytics}
|
||||
disabled={isLoading}
|
||||
variant="secondary"
|
||||
>
|
||||
{isLoading ? '🔄 Actualisation...' : '🔄 Actualiser'}
|
||||
</Button>
|
||||
<div className="flex items-center gap-2">
|
||||
{analytics && (
|
||||
<div className="text-xs text-[var(--muted-foreground)] px-2 py-1 bg-[var(--card)] border border-[var(--border)] rounded">
|
||||
💾 Données en cache
|
||||
</div>
|
||||
)}
|
||||
<Button
|
||||
onClick={refreshAnalytics}
|
||||
disabled={isLoading}
|
||||
variant="secondary"
|
||||
>
|
||||
{isLoading ? '🔄 Actualisation...' : '🔄 Actualiser'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user