Skip to content

Add "filters" title on dashboards#173

Merged
caverav merged 5 commits intodevelopmentfrom
feature/filters-title-on-dashboards
Nov 7, 2024
Merged

Add "filters" title on dashboards#173
caverav merged 5 commits intodevelopmentfrom
feature/filters-title-on-dashboards

Conversation

@massi-ponce
Copy link
Copy Markdown
Collaborator

@massi-ponce massi-ponce commented Nov 7, 2024

Descripción

Se agrega un título para los filtros dentro de los dashboards (tanto para los audit dashboard como para los client dashboard).

Motivación y Contexto

Mejorar UX.

¿Cómo ha sido probado?

  1. Entrar a las secciones de dashboards (audit dashboard y client dashboard).
  2. Verificar que en los gráficos que tienen filtros, salga el título "Filters".

Tipos de cambios

  • Bugfix (cambio que no interrumpe el funcionamiento y que soluciona un problema)
  • New feature (cambio que no interrumpe el funcionamiento y que añade funcionalidad)
  • Breaking change (corrección o funcionalidad que podría causar que la funcionalidad existente cambie)

Lista de verificación:

  • Mi código sigue el estilo de código de este proyecto.
  • Mi cambio requiere una modificación en la documentación.
  • He actualizado la documentación en consecuencia.
  • Requiere nuevos tests.

Summary by CodeRabbit

  • Nuevas Funciones

    • Se ha añadido un título a la leyenda en varios gráficos, mostrando el texto traducido para 'filtros'.
    • Mejora en el formato de las etiquetas de datos para mostrar porcentajes en gráficos de pastel y de tiempo por auditoría.
  • Mejoras Visuales

    • Actualización de los colores de fondo en el gráfico de pastel para la categoría 'Informativa'.
    • Se han realizado mejoras en la presentación visual de los gráficos mediante cambios en el estilo de los títulos y etiquetas.
  • Documentación

    • Se ha añadido una nueva entrada de traducción para 'filters' en el sistema de internacionalización.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 7, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

Se han realizado modificaciones en varios componentes de gráficos en el frontend, específicamente en CIATriadChart.tsx, SeverityPieChart.tsx, TimePerAuditChart.tsx, CIATriad.tsx, y CVSSScore.tsx. Estas modificaciones incluyen la adición de un título en la configuración de la leyenda de los gráficos, que se muestra utilizando una cadena traducida para 'filters'. Además, se han mejorado los formatos de etiquetas de datos en algunos gráficos para calcular y mostrar porcentajes, manteniendo la estructura y lógica general de los componentes.

Changes

Archivo Resumen de cambios
frontend/src/components/charts/CIATriadChart.tsx, frontend/src/components/charts/SeverityPieChart.tsx, frontend/src/components/charts/TimePerAuditChart.tsx, frontend/src/components/dashboard/CIATriad.tsx, frontend/src/components/dashboard/CVSSScore.tsx Se añadió una configuración de título a la leyenda en los gráficos, utilizando la cadena traducida para 'filters', con estilo en color blanco y fuente en negrita. En SeverityPieChart.tsx y TimePerAuditChart.tsx, se mejoró la lógica de formato de etiquetas de datos para calcular y mostrar porcentajes.
frontend/src/i18n/en-US/index.ts Se añadió una nueva entrada filters: 'Filters' en el objeto exportado por defecto, que se utiliza para la localización de textos en la aplicación.

Possibly related PRs

  • ✨ feat: Add functionality to add new findings in audits #128: El SeverityPieChart.tsx y TimePerAuditChart.tsx también mejoran la configuración de la leyenda de sus gráficos al añadir un título con propiedades similares, incluyendo el uso de la cadena traducida para 'filters'.
  • ✨ feat: Add percentage to charts #172: El SeverityPieChart.tsx y TimePerAuditChart.tsx se actualizan para incluir el chartjs-plugin-datalabels, lo que permite mostrar etiquetas de porcentaje, mejorando la representación visual de los datos, de manera similar a los cambios realizados en CIATriadChart.tsx.

Suggested labels

enhancement

Suggested reviewers

  • massi-ponce
  • Icksir
  • jllanosg
  • Sealra

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (8)
frontend/src/components/charts/SeverityPieChart.tsx (2)

45-56: ¡Los cambios en la configuración del título son correctos, pero hay margen de mejora!

La implementación cumple con el objetivo de añadir el título "Filters", sin embargo, los valores de estilo están hardcodeados. Deberías considerar mover estos valores a constantes de tema para mantener la consistencia en toda la aplicación.

Te sugiero este cambio:

+ // En un archivo de constantes de tema
+ export const CHART_TITLE_STYLES = {
+   color: 'white',
+   padding: { top: 20 },
+   font: { weight: 'bold', size: 15 }
+ };

  title: {
    display: true,
    text: t('filters'),
-   color: 'white',
-   padding: {
-     top: 20,
-   },
-   font: {
-     weight: 'bold',
-     size: 15,
-   },
+   ...CHART_TITLE_STYLES
  },

Line range hint 58-69: ¡El cálculo de porcentajes necesita optimización!

La lógica actual funciona, pero está usando un enfoque menos eficiente con forEach. Además, el cálculo del total se está realizando en cada llamada al formatter.

Te propongo esta implementación más eficiente:

  datalabels: {
+   // Calcular el total una sola vez fuera del formatter
+   const totalValue = data.reduce((sum, d) => sum + d.value, 0);
    formatter: (value: number) => {
-     let total = 0;
-     data.forEach(d => {
-       total += d.value;
-     });
-     const percentage = ((value / total) * 100).toFixed(2);
+     const percentage = ((value / totalValue) * 100).toFixed(2);
      if (percentage === '0.00' || percentage === 'NaN') {
        return '';
      }
      return percentage + '%';
    },

Esta implementación:

  1. Evita recalcular el total en cada llamada al formatter
  2. Usa reduce en lugar de forEach, que es más idiomático en JavaScript/TypeScript
  3. Mantiene la misma funcionalidad pero con mejor rendimiento
frontend/src/components/charts/TimePerAuditChart.tsx (2)

65-73: ¡Los valores de estilo deberían usar constantes del tema!

La configuración del título está correcta, pero los valores de estilo están hardcodeados. Esto podría causar problemas de mantenimiento y consistencia visual en el futuro.

Te sugiero refactorizar el código así:

  title: {
    display: true,
    text: t('filters'),
-   color: 'white',
-   font: {
-     weight: 'bold',
-     size: 15,
-   },
+   color: theme.colors.text.primary,
+   font: {
+     weight: theme.typography.weights.bold,
+     size: theme.typography.sizes.medium,
+   },
  },

Line range hint 76-95: ¡La implementación del formatter es ineficiente y poco segura!

El código actual tiene varios problemas serios:

  1. Recalcula el total para cada punto de datos, lo cual es ineficiente
  2. Usa conversiones de tipo poco seguras
  3. La lógica de cálculo es más compleja de lo necesario

Te propongo esta implementación más eficiente y segura:

const calculateTotal = (data: AuditTime[]): number => 
  data.reduce((sum, d) => sum + d.execution + d.remediation, 0);

// En el componente, antes de options:
const total = calculateTotal(data);

// En el formatter:
datalabels: {
  formatter: (value: number) => {
    return `${((value / total) * 100).toFixed(2)}%`;
  },
  color: '#fff' as const,
},

Esta solución:

  • Calcula el total una sola vez
  • Elimina las conversiones de tipo innecesarias
  • Simplifica la lógica del formatter
frontend/src/components/charts/CIATriadChart.tsx (2)

94-102: ¡Extraer valores de estilo a constantes!

La implementación del título funciona, pero hay varios valores "mágicos" que deberían extraerse a constantes. Además, los colores deberían utilizar variables del tema para mantener la consistencia.

Te sugiero aplicar estos cambios:

+ const LEGEND_TITLE_FONT_SIZE = 15;
+ const LEGEND_TITLE_FONT_WEIGHT = 'bold';
+ // Agregar en el archivo de tema
+ const LEGEND_TEXT_COLOR = 'white';

  title: {
    display: true,
    text: t('filters'),
-   color: 'white',
+   color: LEGEND_TEXT_COLOR,
    font: {
-     weight: 'bold',
-     size: 15,
+     weight: LEGEND_TITLE_FONT_WEIGHT,
+     size: LEGEND_TITLE_FONT_SIZE,
    },
  },

Line range hint 1-138: ¡El componente necesita varias mejoras estructurales!

He identificado varios puntos que requieren atención inmediata:

  1. Los valores de las etiquetas de escala ('None', 'Low', 'High') están hardcodeados y deberían estar en constantes o usar i18n.
  2. Los colores están dispersos por todo el código.
  3. No hay optimización de rendimiento para las transformaciones de datos.

Te propongo implementar estos cambios:

+ const CIA_SCALE_LABELS = {
+   NONE: { value: 0, label: t('scale.none') },
+   LOW: { value: 1, label: t('scale.low') },
+   HIGH: { value: 2, label: t('scale.high') },
+ } as const;

+ const CHART_COLORS = {
+   backgroundColor: 'rgba(130, 202, 157, 0.5)',
+   borderColor: 'rgb(130, 202, 157)',
+   gridColor: 'rgba(255, 255, 255, 0.1)',
+ } as const;

export const CIATriadChart: React.FC<Props> = ({ data }) => {
+  const chartData = useMemo(() => ({
     labels: data.map(d => d.subject),
     datasets: [{
       label: 'Average',
       data: data.map(d => d.current),
-      backgroundColor: 'rgba(130, 202, 157, 0.5)',
-      borderColor: 'rgb(130, 202, 157)',
+      backgroundColor: CHART_COLORS.backgroundColor,
+      borderColor: CHART_COLORS.borderColor,
       borderWidth: 1,
     }],
-  });
+  }), [data]);

   // En la configuración de ticks
   callback: (value: number | string) => {
-    if (value === 0) return 'None';
-    if (value === 1) return 'Low';
-    if (value === 2) return 'High';
+    const scaleLabel = Object.values(CIA_SCALE_LABELS).find(
+      label => label.value === value
+    );
+    return scaleLabel?.label ?? value;
   }
frontend/src/components/dashboard/CVSSScore.tsx (2)

98-106: ¡La implementación del título es correcta pero podemos mejorarla!

La adición del título "Filters" está bien implementada, pero sería más mantenible extraer la configuración del estilo a una constante separada. Esto facilitaría la consistencia entre diferentes gráficos y reduciría la duplicación de código.

Te sugiero aplicar este cambio:

+ const CHART_TITLE_STYLE = {
+   display: true,
+   color: 'white',
+   font: {
+     weight: 'bold',
+     size: 15,
+   },
+ };

  const pieChartOptions = {
    responsive: true,
    maintainAspectRatio: false,
    plugins: {
      legend: {
        position: 'right' as const,
        title: {
-         display: true,
-         text: t('filters'),
-         color: 'white',
-         font: {
-           weight: 'bold',
-           size: 15,
-         },
+         ...CHART_TITLE_STYLE,
+         text: t('filters'),
        },

Line range hint 1-144: ¡Hay varios aspectos importantes que necesitan atención!

  1. No hay manejo de estados de carga o error en el componente. Los usuarios no sabrán si hay un problema al cargar los datos.

  2. La función de cálculo de porcentajes en el formateador de datalabels se está recalculando innecesariamente para cada valor.

  3. El componente no tiene tipos TypeScript estrictos para los datos del gráfico.

Te propongo implementar estas mejoras:

+ type ChartData = {
+   labels: string[];
+   datasets: {
+     data: number[];
+     backgroundColor: string[];
+     borderColor: string[];
+     borderWidth: number;
+   }[];
+ };

const CVSSScore: React.FC<CVSSScoreProps> = ({ auditId }) => {
  const paramId = useParams().auditId;
  if (!auditId) {
    auditId = paramId;
  }
- const [pieChartData, setPieChartData] = useState({
+ const [isLoading, setIsLoading] = useState(true);
+ const [error, setError] = useState<string | null>(null);
+ const [pieChartData, setPieChartData] = useState<ChartData>({
    // ... resto del estado inicial
  });

  useEffect(() => {
+   setIsLoading(true);
+   setError(null);
    getAuditById(auditId)
      .then(audit => {
        // ... código existente
+       setIsLoading(false);
      })
-     .catch(console.error);
+     .catch(err => {
+       setError(err.message);
+       setIsLoading(false);
+       console.error(err);
+     });
  }, [auditId]);

+ if (isLoading) return <div>Cargando...</div>;
+ if (error) return <div>Error: {error}</div>;

  return (
    <div className="bg-gray-800 rounded-lg p-6">
      <div className="chart-container" style={{ height: '400px' }}>
        <Pie data={pieChartData} options={pieChartOptions} />
      </div>
    </div>
  );
};

También deberías optimizar el cálculo de porcentajes:

  plugins: {
    datalabels: {
      formatter: (value: number) => {
-       let total = 0;
-       pieChartData.datasets[0].data.forEach(d => {
-         total += d;
-       });
+       const total = pieChartData.datasets[0].data.reduce((sum, d) => sum + d, 0);
        const percentage = ((value / total) * 100).toFixed(2);
        if (percentage === '0.00' || percentage === 'NaN') {
          return '';
        }
        return percentage + '%';
      },
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 44c85b1 and d3a3839.

📒 Files selected for processing (6)
  • frontend/src/components/charts/CIATriadChart.tsx (1 hunks)
  • frontend/src/components/charts/SeverityPieChart.tsx (1 hunks)
  • frontend/src/components/charts/TimePerAuditChart.tsx (1 hunks)
  • frontend/src/components/dashboard/CIATriad.tsx (2 hunks)
  • frontend/src/components/dashboard/CVSSScore.tsx (1 hunks)
  • frontend/src/i18n/en-US/index.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • frontend/src/i18n/en-US/index.ts
🔇 Additional comments (2)
frontend/src/components/dashboard/CIATriad.tsx (1)

10-10: ¡Importación correcta de i18next!

La adición de la función de traducción está bien implementada y sigue las mejores prácticas de internacionalización.

frontend/src/components/dashboard/CVSSScore.tsx (1)

Line range hint 1-3: ¡Necesitamos verificar las dependencias!

El comentario eslint-disable import/no-extraneous-dependencies sugiere que podría haber problemas con las dependencias. Debemos asegurarnos de que todas las dependencias estén correctamente declaradas en el package.json.

Ejecutemos este script para verificar:

Comment on lines +113 to +121
title: {
display: true,
text: t('filters'),
color: 'white',
font: {
weight: 'bold',
size: 15,
},
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

¡La configuración del título necesita mejoras importantes!

La implementación actual tiene varios problemas que necesitan ser corregidos:

  1. El color del texto está hardcodeado a 'white', lo que no es mantenible.
  2. El tamaño de la fuente está hardcodeado a 15px.
  3. No hay consideración para temas oscuros/claros.

Te sugiero aplicar estos cambios:

 title: {
   display: true,
   text: t('filters'),
-  color: 'white',
+  color: 'var(--text-primary)',
   font: {
     weight: 'bold',
-    size: 15,
+    size: 'var(--text-size-title)',
   },
 },

También deberías:

  1. Agregar variables CSS para los colores y tamaños en tu archivo de estilos
  2. Implementar soporte para temas oscuros/claros

¿Necesitas ayuda para implementar un sistema de temas más robusto?

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (1)
frontend/src/components/dashboard/AverageCVSS.tsx (1)

Line range hint 41-123: ¡El manejo de errores es insuficiente!

El componente tiene varios problemas serios:

  1. Solo usas console.error para los errores - ¡los usuarios no ven nada cuando algo falla!
  2. No hay estados de carga
  3. La lógica de cálculo en el useEffect es demasiado compleja

Necesitas:

  1. Agregar estados de carga y error
  2. Extraer la lógica de cálculo
  3. Mostrar mensajes de error al usuario

Te propongo esta estructura:

const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);

const calculateAverageScore = (findings: Finding[]) => {
  return Math.round(
    (findings.reduce((acc, finding) => acc + cvssStringToScore(finding.cvssv3 ?? ''), 0) /
      findings.length) *
      10
  ) / 10;
};

useEffect(() => {
  const fetchData = async () => {
    try {
      setIsLoading(true);
      setError(null);
      
      const result = clientName === undefined
        ? await getAuditById(auditIdRef.current)
        : await getAuditsByClientName(clientName);
        
      setAverageCVSS(calculateAverageScore(result.datas.findings));
      setData(/* ... */);
    } catch (err) {
      setError(err instanceof Error ? err : new Error('Error desconocido'));
    } finally {
      setIsLoading(false);
    }
  };

  fetchData();
}, [auditId, clientName, paramId]);

if (isLoading) return <div>Cargando...</div>;
if (error) return <div>Error: {error.message}</div>;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a0f1a5a and 09557f5.

📒 Files selected for processing (5)
  • frontend/src/components/charts/CIATriadChart.tsx (2 hunks)
  • frontend/src/components/charts/SeverityPieChart.tsx (1 hunks)
  • frontend/src/components/charts/TimePerAuditChart.tsx (1 hunks)
  • frontend/src/components/dashboard/AverageCVSS.tsx (3 hunks)
  • frontend/src/components/dashboard/CIATriad.tsx (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • frontend/src/components/charts/CIATriadChart.tsx
  • frontend/src/components/charts/SeverityPieChart.tsx
  • frontend/src/components/charts/TimePerAuditChart.tsx
  • frontend/src/components/dashboard/CIATriad.tsx


const options: ChartOptions<'bar'> = {
indexAxis: 'y',
indexAxis: 'y' as const,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

¡Las aserciones de tipo pueden mejorarse!

Las aserciones de tipo as const que has agregado son redundantes y hacen el código más verboso. En su lugar, deberías:

  1. Definir las constantes al inicio del archivo
  2. Utilizar un tipo más específico para las opciones del gráfico

Te propongo este cambio:

+ const CHART_COLORS = {
+   GRID: 'rgba(255, 255, 255, 0.1)',
+   TEXT: 'white',
+ } as const;

const options: ChartOptions<'bar'> = {
-  indexAxis: 'y' as const,
+  indexAxis: 'y',
   ...
   ticks: {
-    color: 'white' as const,
+    color: CHART_COLORS.TEXT,
   },
   grid: {
-    color: 'rgba(255, 255, 255, 0.1)' as const,
+    color: CHART_COLORS.GRID,
   }
}

Also applies to: 140-140, 143-143, 148-148

annotations: {
line1: {
type: 'line',
type: 'line' as const,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

¡Más aserciones de tipo innecesarias!

La aserción de tipo para la anotación y el color del borde también pueden mejorarse.

Aplica este cambio junto con las constantes anteriores:

const CHART_COLORS = {
  GRID: 'rgba(255, 255, 255, 0.1)',
  TEXT: 'white',
+ BORDER: '#2ecc71',
} as const;

// En las anotaciones
annotations: {
  line1: {
-   type: 'line' as const,
+   type: 'line',
-   borderColor: '#2ecc71' as const,
+   borderColor: CHART_COLORS.BORDER,
    ...
  }
}

Also applies to: 168-168

@caverav caverav merged commit 8106d82 into development Nov 7, 2024
@caverav caverav deleted the feature/filters-title-on-dashboards branch November 7, 2024 02:35
@coderabbitai coderabbitai Bot mentioned this pull request Nov 13, 2024
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants