caverav / auditforge

AuditForge is a pentest reporting application making it simple and easy to write your findings and generate a customizable report.
https://auditforge.feriadesoftware.cl
MIT License
1 stars 0 forks source link

UI table #18

Closed jllanosg closed 1 month ago

jllanosg commented 1 month ago

Agrega UITable

Tabla reutilizable, creada para mantener estilos entre diferentes vistas de tablas. Se incluye una implementación de ejemplo en la Wiki, IMPORTANTE probarla y modificarla para entender el funcionamiento

VER EJEMPLO

Agrega useSortableTable

Hook creado que permite mantener de manera simple los datos de la tabla ordenados (o no) dependiendo de si se hizo click en una columna que permita realizar el ordenamiento ascendente o descendente.

Agrega useTableFiltering

Hook que permite mantener el estado de los filtros de datos de diferentes origenes (UITable/personalizados), y aplicarle el filtrado a los datos cada vez que se modifiquen los filtros.

Actualiza SimpleInput

Se hace que el prop label sea opcional, de manera en que se pueda ocultar el titulo extra que contiene este componente.

Agrega traducciones

Traducciones all y noMatchingRecords.

iTzGooDLife commented 1 month ago

Creo que está bien, se podría implementar la mejora de que al buscar por un nombre y se obtengan resultados, al eliminar el string del buscador se actualice de forma dinámica y no al apretar el botón (o simplemente que cuando esté vacío vuelva a mostrar la data original), como también poder realizar la búsqueda apretando 'Enter' y no sólo el botón.

image

Creo que está bien implementado, para la barra de búsqueda de nombre se utiliza un children, por lo que tu puedes escoger que agregar ahí, si se quiere implementar eso tiene que verse en el componente de búsqueda y no en este.

iTzGooDLife commented 1 month ago

Considero que abarca todo lo necesario para la tabla y está bien implementado, lo único que modificaría es separar un poco los iconos de la derecha:

image

Una vez conversado y/o modificado lo apruebo :+1:

massi-ponce commented 1 month ago

Todo bien con la tabla en general. Solamente que encontré una forma de "invalidar" los filtros.

Por ejemplo, utilizando el "Ejemplo usando mock data" donde hay un switch para filtrar las edades (mayores que 30), si yo apreto este switch va a desaparecer de la tabla "John Doe", pero si en el filtro de edad escribo "28" o, por otro lado, en el filtro de nombre escribo "John Doe", se hará efectiva la búsqueda de "John Doe" a pesar de tener el filtro de la edad activado.

image

Incluso, si luego limpio las búsquedas (tanto la de edad como la de nombre) me aparecerá "John Doe" en la tabla nuevamente, como si el filtro de edad no estuviese activo.

image

Realmente no sé si este es el comportamiento esperado, si es relevante, muy rebuscado o si es un problema de los filtros solamente y no de la tabla como tal. Pero de igual forma quise hacerlo notar. Por lo demás, siento que la tabla funciona muy bien.

Esperaré algún feedback de este comentario y luego aprobaré.

jllanosg commented 1 month ago

Creo que está bien, se podría implementar la mejora de que al buscar por un nombre y se obtengan resultados, al eliminar el string del buscador se actualice de forma dinámica y no al apretar el botón (o simplemente que cuando esté vacío vuelva a mostrar la data original), como también poder realizar la búsqueda apretando 'Enter' y no sólo el botón.

image

@Sealra Ese cambio es parte de componente SearchInput, no corresponde a este PR.

jllanosg commented 1 month ago

Considero que abarca todo lo necesario para la tabla y está bien implementado, lo único que modificaría es separar un poco los iconos de la derecha:

image

Una vez conversado y/o modificado lo apruebo 👍

@iTzGooDLife eso se pudee ver más adelante, lo que prima ahora es el funcionamiento (lógica) de la tabla i.e. no se vaya a caer/bugear, mas no los estilos/UX.

jllanosg commented 1 month ago

Todo bien con la tabla en general. Solamente que encontré una forma de "invalidar" los filtros.

Por ejemplo, utilizando el "Ejemplo usando mock data" donde hay un switch para filtrar las edades (mayores que 30), si yo apreto este switch va a desaparecer de la tabla "John Doe", pero si en el filtro de edad escribo "28" o, por otro lado, en el filtro de nombre escribo "John Doe", se hará efectiva la búsqueda de "John Doe" a pesar de tener el filtro de la edad activado.

image

Incluso, si luego limpio las búsquedas (tanto la de edad como la de nombre) me aparecerá "John Doe" en la tabla nuevamente, como si el filtro de edad no estuviese activo.

image

Realmente no sé si este es el comportamiento esperado, si es relevante, muy rebuscado o si es un problema de los filtros solamente y no de la tabla como tal. Pero de igual forma quise hacerlo notar. Por lo demás, siento que la tabla funciona muy bien.

Esperaré algún feedback de este comentario y luego aprobaré.

Me parece una buena observación, si bien estos filtros siempre se controlan por fuera del componente UITable, se debe encontrar una manera de "unificar" los filtros aplicados a la data, de manera en que no se solapen y generen errores de inconsistencia. Estaré trabajando en eso

jllanosg commented 1 month ago

Respecto a lo mencionado por @massi-ponce (Max):

Se puede utilizar la función handleFilter (definida en la wiki, ejemplo 1):

const handleFilter = (filters: { [key: string]: string }) => {
    const newFilteredData = data.filter((item) =>
      columns.every((column) => {
        const filterValue = filters[column.accessor];
        if (!filterValue) return true;
        return String(item[column.accessor as keyof TableData]) // IMPORTANTE Definir la TableData (columnas) como tipo para estos casos.
          .toLowerCase()
          .includes(filterValue.toLowerCase());
      })
    );
    setTableData(newFilteredData);
  };

Y luego en el filtro personalizado, en su onClick hacer el llamado a handleFilter con los parámetros adecuados, como se ve en el siguiente ejemplo:

<div>
      <h1>Generic Table Example</h1>
      <UITable
        columns={columns}
        data={tableData}
        keyExtractor={keyExtractor}
        onSort={handleSorting}
        onFilter={handleFilter}
        rowActions={rowActions}
        emptyState={<div>{t("err.noMatchingRecords")}</div>}
      >
        <div className="flex justify-between">
          <SearchInput
            label={"Ejemplo filtro de nombre"}
            id="nameFilter"
            name="nameFilter"
            type="text"
            placeholder="filter name..."
            value={nameFilter}
            onChange={(val) => setNameFilter(val)}
            onClick={() => handleFilter({ name: nameFilter })} // ACA
            buttonLabel=""
          />
        </div>
      </UITable>
    </div>

Para generalizar esto, se verá la posibilidad de pasar esta función a utils para poder importarla en cualquier parte y no repetir código.