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

Backport/#320 #365 #366 #379 #391

Merged
merged 6 commits into from
Sep 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

jobs:
backend:
timeout-minutes: 20
timeout-minutes: 40
strategy:
matrix:
node-version: [16.x]
Expand Down
2 changes: 2 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pyngrok = "==5.1"
flask-talisman = "==1.0"
gevent = "==21.12.0"
gevent-websocket = "==0.10.1"
kthread = "==0.2.3"
werkzeug = "==2.0.3"

[dev-packages]
black = "*"
Expand Down
2 changes: 2 additions & 0 deletions gui/doc/input.csv
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ password,bool,False,"If True, the text is obscured: all input characters are dis
label,str,None,The label associated with the input.
>sharedInput,,,
>on_change,,,
multiline,bool,False,"If True, the text is presented as a multi line input."
lines_shown,int,5,"The height of the displayed element if multiline is True."
>propagate,,,
2 changes: 2 additions & 0 deletions gui/doc/table.csv
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ width,str|int|float,"""100vw""","The width, in CSS units, of this table control.
height,str|int|float,"""80vh""","The height, in CSS units, of this table control."
nan_value,str,"""""",The replacement text for NaN (not-a-number) values.
nan_value[<i>col_name</i>],str,"""""",The replacement text for NaN (not-a-number) values for the indicated column.
editable,dynamic(bool),FALSE,"Indicates, if True, that all columns can be edited."
editable[<i>col_name</i>],bool,"editable","Indicates, if False, that the indicated column cannot be edited when editable is True."
on_edit,Callback,,"The name of a function that is to be triggered when a cell edition is validated.<br/>
All parameters of that function are optional:
<ul>
Expand Down
2 changes: 1 addition & 1 deletion gui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "taipy-gui",
"version": "1.1.0",
"version": "1.1.3",
"private": true,
"dependencies": {
"@emotion/react": "^11.5.0",
Expand Down
102 changes: 54 additions & 48 deletions gui/src/components/Taipy/AutoLoadingTable.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState, useEffect, useContext, useCallback, useRef, useMemo, CSSProperties, MouseEvent } from "react";
import Box from "@mui/material/Box";
import MuiTable from "@mui/material/Table";
import TableCell from "@mui/material/TableCell";
import TableCell, { TableCellProps } from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
Expand All @@ -26,7 +26,6 @@ import {
} from "../../context/taipyReducers";
import {
ColumnDesc,
getCellProps,
getsortByIndex,
Order,
TaipyTableProps,
Expand All @@ -39,11 +38,11 @@ import {
RowValue,
EDIT_COL,
OnRowDeletion,
iconInRowSx,
addDeleteColumn,
headBoxSx,
getClassName,
LINE_STYLE,
iconInRowSx,
} from "./tableUtils";
import { useDispatchRequestUpdateOnFirstRender, useDynamicProperty, useFormatConfig } from "../../utils/hooks";

Expand All @@ -52,7 +51,7 @@ interface RowData {
columns: Record<string, ColumnDesc>;
rows: RowType[];
classes: Record<string, string>;
cellStyles: CSSProperties[];
cellProps: Partial<TableCellProps>[];
isItemLoaded: (index: number) => boolean;
selection: number[];
formatConfig: FormatConfig;
Expand All @@ -70,7 +69,7 @@ const Row = ({
columns,
rows,
classes,
cellStyles,
cellProps,
isItemLoaded,
selection,
formatConfig,
Expand All @@ -96,24 +95,18 @@ const Row = ({
selected={selection.indexOf(index) > -1}
>
{colsOrder.map((col, cidx) => (
<TableCell
component="div"
variant="body"
<EditableCell
key={"val" + index + "-" + cidx}
{...getCellProps(columns[col])}
sx={cellStyles[cidx]}
className={getClassName(rows[index], columns[col].style)}
>
<EditableCell
colDesc={columns[col]}
value={rows[index][col]}
formatConfig={formatConfig}
rowIndex={index}
onValidation={onValidation}
onDeletion={onDeletion}
nanValue={columns[col].nanValue || nanValue}
/>
</TableCell>
colDesc={columns[col]}
value={rows[index][col]}
formatConfig={formatConfig}
rowIndex={index}
onValidation={onValidation}
onDeletion={onDeletion}
nanValue={columns[col].nanValue || nanValue}
tableCellProps={cellProps[cidx]}
/>
))}
</TableRow>
) : (
Expand Down Expand Up @@ -181,13 +174,16 @@ const AutoLoadingTable = (props: TaipyTableProps) => {

useDispatchRequestUpdateOnFirstRender(dispatch, id, updateVars);

const handleRequestSort = useCallback(
(event: React.MouseEvent<unknown>, col: string) => {
const isAsc = orderBy === col && order === "asc";
setOrder(isAsc ? "desc" : "asc");
setOrderBy(col);
setRows([]);
setTimeout(() => infiniteLoaderRef.current?.resetloadMoreItemsCache(true), 1); // So that the state can be changed
const onSort = useCallback(
(e: React.MouseEvent<HTMLElement>) => {
const col = e.currentTarget.getAttribute("data-dfid");
if (col) {
const isAsc = orderBy === col && order === "asc";
setOrder(isAsc ? "desc" : "asc");
setOrderBy(col);
setRows([]);
setTimeout(() => infiniteLoaderRef.current?.resetloadMoreItemsCache(true), 1); // So that the state can be changed
}
},
[orderBy, order]
);
Expand All @@ -199,13 +195,6 @@ const AutoLoadingTable = (props: TaipyTableProps) => {
}
}, [props.data]);

const createSortHandler = useCallback(
(col: string) => (event: MouseEvent<unknown>) => {
handleRequestSort(event, col);
},
[handleRequestSort]
);

const onAggregate = useCallback((e: MouseEvent<HTMLElement>) => {
const groupBy = e.currentTarget.getAttribute("data-dfid");
if (groupBy) {
Expand All @@ -224,7 +213,16 @@ const AutoLoadingTable = (props: TaipyTableProps) => {
let hNan = !!props.nanValue;
if (props.columns) {
try {
const columns = typeof props.columns === "string" ? JSON.parse(props.columns) : props.columns;
const columns = (
typeof props.columns === "string" ? JSON.parse(props.columns) : props.columns
) as Record<string, ColumnDesc>;
Object.values(columns).forEach((col) => {
if (typeof col.notEditable != "boolean") {
col.notEditable = !editable;
} else {
col.notEditable = col.notEditable || !editable;
}
});
addDeleteColumn(!!(active && editable && (tp_onAdd || tp_onDelete)), columns);
const colsOrder = Object.keys(columns).sort(getsortByIndex(columns));
const styles = colsOrder.reduce<Record<string, unknown>>((pv, col) => {
Expand Down Expand Up @@ -363,9 +361,10 @@ const AutoLoadingTable = (props: TaipyTableProps) => {
columns: columns,
rows: rows,
classes: {},
cellStyles: colsOrder.map((col) => ({
width: columns[col].width || columns[col].widthHint,
height: ROW_HEIGHT - 32,
cellProps: colsOrder.map((col) => ({
sx: { width: columns[col].width || columns[col].widthHint, height: ROW_HEIGHT - 32 },
component: "div",
variant: "body",
})),
isItemLoaded: isItemLoaded,
selection: selected,
Expand Down Expand Up @@ -416,16 +415,23 @@ const AutoLoadingTable = (props: TaipyTableProps) => {
width={columns[col].width}
>
{columns[col].dfid === EDIT_COL ? (
active && editable && tp_onAdd ? (
<IconButton onClick={onAddRowClick} size="small" sx={iconInRowSx}>
<AddIcon />
</IconButton>
) : null
active && editable && tp_onAdd ? (
<Tooltip title="Add a row" key="addARow">
<IconButton
onClick={onAddRowClick}
size="small"
sx={iconInRowSx}
>
<AddIcon fontSize="inherit" />
</IconButton>
</Tooltip>
) : null
) : (
<TableSortLabel
active={orderBy === columns[col].dfid}
direction={orderBy === columns[col].dfid ? order : "asc"}
onClick={createSortHandler(columns[col].dfid)}
data-dfid={columns[col].dfid}
onClick={onSort}
disabled={!active}
>
<Box sx={headBoxSx}>
Expand All @@ -434,14 +440,14 @@ const AutoLoadingTable = (props: TaipyTableProps) => {
onClick={onAggregate}
size="small"
title="aggregate"
sx={iconInRowSx}
data-dfid={columns[col].dfid}
disabled={!active}
sx={iconInRowSx}
>
{aggregates.includes(columns[col].dfid) ? (
<DataSaverOff />
<DataSaverOff fontSize="inherit" />
) : (
<DataSaverOn />
<DataSaverOn fontSize="inherit" />
)}
</IconButton>
) : null}
Expand Down
19 changes: 16 additions & 3 deletions gui/src/components/Taipy/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,22 @@ const getActionKeys = (keys?: string): string[] => {
};

const Input = (props: TaipyInputProps) => {
const { className, type, id, updateVarName, propagate = true, defaultValue = "", tp_onAction, tp_onChange } = props;
const {
className,
type,
id,
updateVarName,
propagate = true,
defaultValue = "",
tp_onAction,
tp_onChange,
multiline = false,
linesShown = 5,
} = props;
const [value, setValue] = useState(defaultValue);
const { dispatch } = useContext(TaipyContext);
const delayCall = useRef(-1);
const [actionKeys] = useState(() => tp_onAction ? getActionKeys(props.actionKeys): []);
const [actionKeys] = useState(() => (tp_onAction ? getActionKeys(props.actionKeys) : []));

const changeDelay = typeof props.changeDelay === "number" && props.changeDelay >= 0 ? props.changeDelay : 300;
const active = useDynamicProperty(props.active, props.defaultActive, true);
Expand Down Expand Up @@ -76,14 +87,16 @@ const Input = (props: TaipyInputProps) => {
<TextField
margin="dense"
hiddenLabel
value={value}
value={value || ""}
className={className}
type={type}
id={id}
label={props.label}
onChange={handleInput}
disabled={!active}
onKeyDown={tp_onAction ? handleAction : undefined}
multiline={multiline}
minRows={linesShown}
/>
</Tooltip>
);
Expand Down
Loading