Skip to content
This repository has been archived by the owner on Nov 2, 2024. It is now read-only.

Commit

Permalink
Visualizer improvements (intelowlproject#2366)
Browse files Browse the repository at this point in the history
* table visualizer improvements

* adjusted tests

* prettier

* changes
  • Loading branch information
carellamartina authored and Michalsus committed Oct 11, 2024
1 parent a3d5945 commit 9bb8f8c
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 61 deletions.
61 changes: 53 additions & 8 deletions api_app/visualizers_manager/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
VisualizableIcon,
VisualizableLevelSize,
VisualizableSize,
VisualizableTableColumnSize,
)
from api_app.visualizers_manager.exceptions import (
VisualizerConfigurationException,
Expand Down Expand Up @@ -208,7 +209,7 @@ def __init__(
f"value {v} should be a VisualizableObject and not a string"
)
if fill_empty and not value:
value = [VisualizableBase(value="no data available", disable=False)]
value = [VisualizableBase(value="no data available", disable=True)]
if not name:
start_open = True
self.value = value
Expand Down Expand Up @@ -261,32 +262,67 @@ def type(self) -> str:
return "vertical_list"


class VisualizableTableColumn:
def __init__(
self,
name: str,
max_width: VisualizableTableColumnSize = VisualizableTableColumnSize.S_300,
description: str = "",
disable_filters: bool = False,
disable_sort_by: bool = False,
):
self.name = name
self.description = description
self.disable_filters = disable_filters
self.disable_sort_by = disable_sort_by
self.max_width = max_width

@property
def attributes(self) -> List[str]:
return [
"name",
"description",
"disable_filters",
"disable_sort_by",
"max_width",
]

def to_dict(self) -> Dict:
if not self:
return {}
result = {attr: getattr(self, attr) for attr in self.attributes}
for key, value in result.items():
if isinstance(value, Enum):
result[key] = value.value
return result


class VisualizableTable(VisualizableObject):
def __init__(
self,
columns: List[str],
columns: List[VisualizableTableColumn],
data: List[Dict[str, VisualizableObject]],
size: VisualizableSize = VisualizableSize.S_AUTO,
alignment: VisualizableAlignment = VisualizableAlignment.AROUND,
page_size: int = 5,
disable_filters: bool = False,
disable_sort_by: bool = False,
sort_by_id: str = "",
sort_by_desc: bool = False,
):
super().__init__(size=size, alignment=alignment, disable=False)
self.data = data
self.columns = columns
self.page_size = page_size
self.disable_filters = disable_filters
self.disable_sort_by = disable_sort_by
self.sort_by_id = sort_by_id
self.sort_by_desc = sort_by_desc

@property
def attributes(self) -> List[str]:
return super().attributes + [
"data",
"columns",
"page_size",
"disable_filters",
"disable_sort_by",
"sort_by_id",
"sort_by_desc",
]

@property
Expand All @@ -296,6 +332,7 @@ def type(self) -> str:
def to_dict(self) -> Dict:
result = super().to_dict()
data: List[Dict[str, VisualizableObject]] = result.pop("data", [])
columns: List[VisualizableTableColumn] = result.pop("columns", [])
if any(x for x in data):
new_data = []
for element in data:
Expand All @@ -309,6 +346,12 @@ def to_dict(self) -> Dict:
result["data"] = new_data
else:
result["data"] = []
if any(x for x in columns):
result["columns"] = [
column.to_dict() for column in columns if column is not None
]
else:
result["columns"] = []
result.pop("disable")
return result

Expand Down Expand Up @@ -384,6 +427,8 @@ class Visualizer(Plugin, metaclass=abc.ABCMeta):
HList = VisualizableHorizontalList
Table = VisualizableTable

TableColumn = VisualizableTableColumn

LevelSize = VisualizableLevelSize
Page = VisualizablePage
Level = VisualizableLevel
Expand Down
14 changes: 14 additions & 0 deletions api_app/visualizers_manager/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,17 @@ def __str__(self):

def __bool__(self):
return True


class VisualizableTableColumnSize(enum.Enum):
"""Column size for VisualizebleTable elements"""

S_50 = 50
S_100 = 100
S_150 = 150
S_200 = 200
S_250 = 250
S_300 = 300

def __str__(self):
return self.value
58 changes: 36 additions & 22 deletions frontend/src/components/jobs/result/visualizer/elements/table.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from "react";
import PropTypes from "prop-types";
import { UncontrolledTooltip } from "reactstrap";
import { DataTable, DefaultColumnFilter } from "@certego/certego-ui";

import { VerticalListVisualizer } from "./verticalList";
import { HorizontalListVisualizer } from "./horizontalList";
import { markdownToHtml } from "../../../../common/markdownToHtml";

function getAccessor(element) {
if ([VerticalListVisualizer, HorizontalListVisualizer].includes(element.type))
Expand All @@ -12,44 +14,58 @@ function getAccessor(element) {
return element.props.value;
}

export function TableVisualizer({
id,
size,
columns,
data,
pageSize,
disableFilters,
disableSortBy,
}) {
export function TableVisualizer({ id, size, columns, data, pageSize, sortBy }) {
const tableColumns = [];

columns.forEach((column) => {
const columnHeader = column.replaceAll("_", " ");
const columnHeader = column.name.replaceAll("_", " ");
const columnElement = (
<>
<span id={`${column.name}-header`}>{columnHeader}</span>
{column.description && (
<UncontrolledTooltip
target={`${column.name}-header`}
placement="top"
fade={false}
style={{
paddingTop: "1rem",
paddingLeft: "1rem",
paddingRight: "1rem",
}}
>
{markdownToHtml(column.description)}
</UncontrolledTooltip>
)}
</>
);

tableColumns.push({
Header: columnHeader,
id: column,
accessor: (row) => getAccessor(row[column]),
Header: columnElement,
id: column.name,
accessor: (row) => getAccessor(row[column.name]),
Cell: ({
cell: {
row: { original },
},
}) => original[column],
disableFilters,
disableSortBy,
}) => original[column.name],
disableFilters: column.disableFilters,
disableSortBy: column.disableSortBy,
Filter: DefaultColumnFilter,
maxWidth: column.maxWidth,
});
});

const tableConfig = {};
const tableInitialState = {
pageSize,
sortBy,
};

return (
<div
id={id}
className={size}
style={{ maxHeight: "60vh", overflowY: "scroll" }}
style={{ maxHeight: "80vh", overflowY: "scroll" }}
>
<DataTable
id={id}
Expand All @@ -65,15 +81,13 @@ export function TableVisualizer({
TableVisualizer.propTypes = {
id: PropTypes.string.isRequired,
size: PropTypes.string.isRequired,
columns: PropTypes.arrayOf(PropTypes.string).isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
data: PropTypes.array.isRequired,
pageSize: PropTypes.number,
disableFilters: PropTypes.bool,
disableSortBy: PropTypes.bool,
sortBy: PropTypes.array,
};

TableVisualizer.defaultProps = {
pageSize: 5,
disableFilters: false,
disableSortBy: false,
sortBy: [],
};
24 changes: 21 additions & 3 deletions frontend/src/components/jobs/result/visualizer/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ function parseElementSize(value) {
return "col-auto";
}

function parseElementWidth(value) {
if ([50, 100, 150, 200, 250, 300].includes(value)) {
return value;
}
return 300;
}

function parseComponentType(value) {
if (
[
Expand Down Expand Up @@ -112,6 +119,17 @@ function parseElementListOfDict(rawElementList) {
});
}

// parse list of Column Elements
function parseColumnElementList(rawElementList) {
return {
name: parseString(rawElementList.name),
maxWidth: parseElementWidth(rawElementList.max_width),
description: parseString(rawElementList.description),
disableFilters: parseBool(rawElementList.disable_filters),
disableSortBy: parseBool(rawElementList.disable_sort_by),
};
}

// parse a single element
function parseElementFields(rawElement) {
// HList and Title don't have disable field, they will not be used
Expand Down Expand Up @@ -156,11 +174,11 @@ function parseElementFields(rawElement) {
case VisualizerComponentType.TABLE: {
validatedFields.data = parseElementListOfDict(rawElement.data || []);
validatedFields.columns = rawElement.columns.map((column) =>
parseString(column),
parseColumnElementList(column),
);
validatedFields.pageSize = rawElement.page_size;
validatedFields.disableFilters = parseBool(rawElement.disable_filters);
validatedFields.disableSortBy = parseBool(rawElement.disable_sort_by);
validatedFields.sortById = parseString(rawElement.sort_by_id);
validatedFields.sortByDesc = parseBool(rawElement.sort_by_desc);
break;
}
// base case
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ function convertToElement(element, idElement, isChild = false) {
return obj;
})}
pageSize={element.pageSize}
disableFilters={element.disableFilters}
disableSortBy={element.disableSortBy}
sortBy={[{ id: element.sortById, desc: element.sortByDesc }]}
/>
);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ describe("TableVisualizer component", () => {
<TableVisualizer
id="test-id"
size="col-6"
columns={["column_name"]}
columns={[
{
name: "column_name",
maxWidth: 300,
description: "test description",
},
]}
data={[
{
column_name: (
Expand Down Expand Up @@ -73,7 +79,15 @@ describe("TableVisualizer component", () => {
id="test-id"
size="col-6"
alignment="around"
columns={["column_name"]}
columns={[
{
name: "column_name",
maxWidth: 300,
description: "test description",
disableFilters: true,
disableSortBy: true,
},
]}
data={[
{
column_name: (
Expand All @@ -86,8 +100,7 @@ describe("TableVisualizer component", () => {
},
]}
pageSize={3}
disableFilters
disableSortBy
sortBy={[{ id: "column_name", desc: false }]}
/>,
);

Expand Down
Loading

0 comments on commit 9bb8f8c

Please sign in to comment.