mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-25 18:18:44 +00:00
CE-1115 checkpoint on report & pivotTable setup widgets:
- refactor into sub-components - working drag & drop - more help content - disable things rather than alert if no table
This commit is contained in:
@ -30,19 +30,88 @@ import Grid from "@mui/material/Grid";
|
||||
import Icon from "@mui/material/Icon";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Tooltip from "@mui/material/Tooltip/Tooltip";
|
||||
import QContext from "QContext";
|
||||
import colors from "qqq/assets/theme/base/colors";
|
||||
import FieldAutoComplete from "qqq/components/misc/FieldAutoComplete";
|
||||
import HelpContent, {hasHelpContent} from "qqq/components/misc/HelpContent";
|
||||
import {PivotTableGroupByElement} from "qqq/components/widgets/misc/PivotTableGroupByElement";
|
||||
import {PivotTableValueElement} from "qqq/components/widgets/misc/PivotTableValueElement";
|
||||
import Widget, {HeaderToggleComponent} from "qqq/components/widgets/Widget";
|
||||
import {PivotObjectKey, PivotTableDefinition, PivotTableFunction, pivotTableFunctionLabels, PivotTableGroupBy, PivotTableValue} from "qqq/models/misc/PivotTableDefinitionModels";
|
||||
import QQueryColumns from "qqq/models/query/QQueryColumns";
|
||||
import Client from "qqq/utils/qqq/Client";
|
||||
import FilterUtils from "qqq/utils/qqq/FilterUtils";
|
||||
import React, {useEffect, useReducer, useState} from "react";
|
||||
import React, {useCallback, useContext, useEffect, useReducer, useState} from "react";
|
||||
import {DndProvider} from "react-dnd";
|
||||
import {HTML5Backend} from "react-dnd-html5-backend";
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// put a unique key value in all the pivot table group-by and value objects, //
|
||||
// to help react rendering be sane. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
let pivotObjectKey = new Date().getTime();
|
||||
export const DragItemTypes =
|
||||
{
|
||||
ROW: "row",
|
||||
COLUMN: "column",
|
||||
VALUE: "value"
|
||||
};
|
||||
|
||||
export const buttonSX =
|
||||
{
|
||||
border: `1px solid ${colors.grayLines.main} !important`,
|
||||
borderRadius: "0.75rem",
|
||||
textTransform: "none",
|
||||
fontSize: "1rem",
|
||||
fontWeight: "400",
|
||||
width: "160px",
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
color: colors.dark.main,
|
||||
"&:hover": {color: colors.dark.main},
|
||||
"&:focus": {color: colors.dark.main},
|
||||
"&:focus:not(:hover)": {color: colors.dark.main},
|
||||
};
|
||||
|
||||
export const xIconButtonSX =
|
||||
{
|
||||
border: `1px solid ${colors.grayLines.main} !important`,
|
||||
borderRadius: "0.75rem",
|
||||
textTransform: "none",
|
||||
fontSize: "1rem",
|
||||
fontWeight: "400",
|
||||
width: "40px",
|
||||
minWidth: "40px",
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
color: colors.error.main,
|
||||
"&:hover": {color: colors.error.main},
|
||||
"&:focus": {color: colors.error.main},
|
||||
"&:focus:not(:hover)": {color: colors.error.main},
|
||||
};
|
||||
|
||||
export const fieldAutoCompleteTextFieldSX =
|
||||
{
|
||||
"& .MuiInputBase-input": {fontSize: "1rem", padding: "0 !important"}
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
export function getSelectedFieldForAutoComplete(tableMetaData: QTableMetaData, fieldName: string)
|
||||
{
|
||||
if (fieldName)
|
||||
{
|
||||
let [field, fieldTable] = FilterUtils.getField(tableMetaData, fieldName);
|
||||
if (field && fieldTable)
|
||||
{
|
||||
return ({field: field, table: fieldTable, fieldName: fieldName});
|
||||
}
|
||||
}
|
||||
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** component props
|
||||
*******************************************************************************/
|
||||
interface PivotTableSetupWidgetProps
|
||||
{
|
||||
isEditable: boolean;
|
||||
@ -51,71 +120,14 @@ interface PivotTableSetupWidgetProps
|
||||
onSaveCallback?: (values: { [name: string]: any }) => void;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** default values for props
|
||||
*******************************************************************************/
|
||||
PivotTableSetupWidget.defaultProps = {
|
||||
onSaveCallback: null
|
||||
};
|
||||
|
||||
export class PivotTableDefinition
|
||||
{
|
||||
rows: PivotTableGroupBy[];
|
||||
columns: PivotTableGroupBy[];
|
||||
values: PivotTableValue[];
|
||||
}
|
||||
|
||||
export class PivotTableGroupBy
|
||||
{
|
||||
fieldName: string;
|
||||
key: number;
|
||||
|
||||
constructor()
|
||||
{
|
||||
this.key = pivotObjectKey++;
|
||||
}
|
||||
}
|
||||
|
||||
export class PivotTableValue
|
||||
{
|
||||
fieldName: string;
|
||||
function: PivotTableFunction;
|
||||
|
||||
key: number;
|
||||
|
||||
constructor()
|
||||
{
|
||||
this.key = pivotObjectKey++;
|
||||
}
|
||||
}
|
||||
|
||||
enum PivotTableFunction
|
||||
{
|
||||
AVERAGE = "AVERAGE",
|
||||
COUNT = "COUNT",
|
||||
COUNT_NUMS = "COUNT_NUMS",
|
||||
MAX = "MAX",
|
||||
MIN = "MIN",
|
||||
PRODUCT = "PRODUCT",
|
||||
STD_DEV = "STD_DEV",
|
||||
STD_DEVP = "STD_DEVP",
|
||||
SUM = "SUM",
|
||||
VAR = "VAR",
|
||||
VARP = "VARP",
|
||||
}
|
||||
|
||||
const pivotTableFunctionLabels =
|
||||
{
|
||||
"AVERAGE": "Average",
|
||||
"COUNT": "Count Values (COUNTA)",
|
||||
"COUNT_NUMS": "Count Numbers (COUNT)",
|
||||
"MAX": "Max",
|
||||
"MIN": "Min",
|
||||
"PRODUCT": "Product",
|
||||
"STD_DEV": "StdDev",
|
||||
"STD_DEVP": "StdDevp",
|
||||
"SUM": "Sum",
|
||||
"VAR": "Var",
|
||||
"VARP": "Varp"
|
||||
};
|
||||
|
||||
|
||||
const qController = Client.getInstance();
|
||||
|
||||
@ -134,54 +146,62 @@ export default function PivotTableSetupWidget({isEditable, widgetMetaData, recor
|
||||
const [pivotTableDefinition, setPivotTableDefinition] = useState(null as PivotTableDefinition);
|
||||
|
||||
const [usedGroupByFieldNames, setUsedGroupByFieldNames] = useState([] as string[]);
|
||||
const [availableFieldNames, setAvailableFieldNames] = useState([] as string[]);
|
||||
|
||||
const {helpHelpActive} = useContext(QContext);
|
||||
|
||||
//////////////////
|
||||
// initial load //
|
||||
//////////////////
|
||||
useEffect(() =>
|
||||
{
|
||||
(async () =>
|
||||
if (!pivotTableDefinition)
|
||||
{
|
||||
if (!pivotTableDefinition)
|
||||
let originalPivotTableDefinition = recordValues["pivotTableJson"] && JSON.parse(recordValues["pivotTableJson"]) as PivotTableDefinition;
|
||||
if (originalPivotTableDefinition)
|
||||
{
|
||||
let originalPivotTableDefinition = recordValues["pivotTableJson"] && JSON.parse(recordValues["pivotTableJson"]) as PivotTableDefinition;
|
||||
if (originalPivotTableDefinition)
|
||||
{
|
||||
setEnabled(true);
|
||||
}
|
||||
else if (!originalPivotTableDefinition)
|
||||
{
|
||||
originalPivotTableDefinition = new PivotTableDefinition();
|
||||
}
|
||||
|
||||
for (let i = 0; i < originalPivotTableDefinition?.rows?.length; i++)
|
||||
{
|
||||
if (!originalPivotTableDefinition?.rows[i].key)
|
||||
{
|
||||
originalPivotTableDefinition.rows[i].key = pivotObjectKey++;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < originalPivotTableDefinition?.columns?.length; i++)
|
||||
{
|
||||
if (!originalPivotTableDefinition?.columns[i].key)
|
||||
{
|
||||
originalPivotTableDefinition.columns[i].key = pivotObjectKey++;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < originalPivotTableDefinition?.values?.length; i++)
|
||||
{
|
||||
if (!originalPivotTableDefinition?.values[i].key)
|
||||
{
|
||||
originalPivotTableDefinition.values[i].key = pivotObjectKey++;
|
||||
}
|
||||
}
|
||||
|
||||
setPivotTableDefinition(originalPivotTableDefinition);
|
||||
setEnabled(true);
|
||||
}
|
||||
else if (!originalPivotTableDefinition)
|
||||
{
|
||||
originalPivotTableDefinition = new PivotTableDefinition();
|
||||
}
|
||||
|
||||
for (let i = 0; i < originalPivotTableDefinition?.rows?.length; i++)
|
||||
{
|
||||
if (!originalPivotTableDefinition?.rows[i].key)
|
||||
{
|
||||
originalPivotTableDefinition.rows[i].key = PivotObjectKey.next();
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < originalPivotTableDefinition?.columns?.length; i++)
|
||||
{
|
||||
if (!originalPivotTableDefinition?.columns[i].key)
|
||||
{
|
||||
originalPivotTableDefinition.columns[i].key = PivotObjectKey.next();
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < originalPivotTableDefinition?.values?.length; i++)
|
||||
{
|
||||
if (!originalPivotTableDefinition?.values[i].key)
|
||||
{
|
||||
originalPivotTableDefinition.values[i].key = PivotObjectKey.next();
|
||||
}
|
||||
}
|
||||
|
||||
setPivotTableDefinition(originalPivotTableDefinition);
|
||||
updateUsedGroupByFieldNames(originalPivotTableDefinition);
|
||||
}
|
||||
|
||||
if(recordValues["columnsJson"])
|
||||
{
|
||||
updateAvailableFieldNames(JSON.parse(recordValues["columnsJson"]) as QQueryColumns)
|
||||
}
|
||||
|
||||
(async () =>
|
||||
{
|
||||
setMetaData(await qController.loadMetaData());
|
||||
})();
|
||||
});
|
||||
@ -202,6 +222,27 @@ export default function PivotTableSetupWidget({isEditable, widgetMetaData, recor
|
||||
}, [recordValues]);
|
||||
|
||||
|
||||
const helpRoles = isEditable ? [recordValues["id"] ? "EDIT_SCREEN" : "INSERT_SCREEN", "WRITE_SCREENS", "ALL_SCREENS"] : ["VIEW_SCREEN", "READ_SCREENS", "ALL_SCREENS"];
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
function showHelp(slot: string)
|
||||
{
|
||||
return (helpHelpActive || hasHelpContent(widgetMetaData?.helpContent?.get(slot), helpRoles));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
function getHelpContent(slot: string)
|
||||
{
|
||||
const key = `widget:${widgetMetaData.name};slot:${slot}`;
|
||||
return <HelpContent helpContents={widgetMetaData?.helpContent?.get(slot)} roles={helpRoles} helpContentKey={key} />;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@ -241,9 +282,8 @@ export default function PivotTableSetupWidget({isEditable, widgetMetaData, recor
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
function removeGroupBy(index: number, rowsOrColumns: "rows" | "columns")
|
||||
function groupByChangedCallback()
|
||||
{
|
||||
pivotTableDefinition[rowsOrColumns].splice(index, 1);
|
||||
onSaveCallback({pivotTableJson: JSON.stringify(pivotTableDefinition)});
|
||||
updateUsedGroupByFieldNames();
|
||||
forceUpdate();
|
||||
@ -277,130 +317,41 @@ export default function PivotTableSetupWidget({isEditable, widgetMetaData, recor
|
||||
}
|
||||
|
||||
|
||||
const buttonSX =
|
||||
{
|
||||
border: `1px solid ${colors.grayLines.main} !important`,
|
||||
borderRadius: "0.75rem",
|
||||
textTransform: "none",
|
||||
fontSize: "1rem",
|
||||
fontWeight: "400",
|
||||
width: "160px",
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
color: colors.dark.main,
|
||||
"&:hover": {color: colors.dark.main},
|
||||
"&:focus": {color: colors.dark.main},
|
||||
"&:focus:not(:hover)": {color: colors.dark.main},
|
||||
};
|
||||
|
||||
const xIconButtonSX =
|
||||
{
|
||||
border: `1px solid ${colors.grayLines.main} !important`,
|
||||
borderRadius: "0.75rem",
|
||||
textTransform: "none",
|
||||
fontSize: "1rem",
|
||||
fontWeight: "400",
|
||||
width: "40px",
|
||||
minWidth: "40px",
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
color: colors.error.main,
|
||||
"&:hover": {color: colors.error.main},
|
||||
"&:focus": {color: colors.error.main},
|
||||
"&:focus:not(:hover)": {color: colors.error.main},
|
||||
};
|
||||
|
||||
const fieldAutoCompleteTextFieldSX =
|
||||
{
|
||||
"& .MuiInputBase-input": {fontSize: "1rem", padding: "0 !important"}
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
function updateUsedGroupByFieldNames()
|
||||
function updateUsedGroupByFieldNames(ptd: PivotTableDefinition = pivotTableDefinition)
|
||||
{
|
||||
const hiddenFieldNames: string[] = [];
|
||||
const usedFieldNames: string[] = [];
|
||||
|
||||
for (let i = 0; i < pivotTableDefinition?.rows?.length; i++)
|
||||
for (let i = 0; i < ptd?.rows?.length; i++)
|
||||
{
|
||||
hiddenFieldNames.push(pivotTableDefinition?.rows[i].fieldName);
|
||||
usedFieldNames.push(ptd?.rows[i].fieldName);
|
||||
}
|
||||
|
||||
for (let i = 0; i < pivotTableDefinition?.columns?.length; i++)
|
||||
for (let i = 0; i < ptd?.columns?.length; i++)
|
||||
{
|
||||
hiddenFieldNames.push(pivotTableDefinition?.columns[i].fieldName);
|
||||
usedFieldNames.push(ptd?.columns[i].fieldName);
|
||||
}
|
||||
|
||||
setUsedGroupByFieldNames(hiddenFieldNames);
|
||||
setUsedGroupByFieldNames(usedFieldNames);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
function getSelectedFieldForAutoComplete(fieldName: string)
|
||||
function updateAvailableFieldNames(columns: QQueryColumns)
|
||||
{
|
||||
if (fieldName)
|
||||
const fieldNames: string[] = [];
|
||||
for (let i = 0; i < columns?.columns?.length; i++)
|
||||
{
|
||||
let [field, fieldTable] = FilterUtils.getField(tableMetaData, fieldName);
|
||||
if (field && fieldTable)
|
||||
if(columns.columns[i].isVisible)
|
||||
{
|
||||
return ({field: field, table: fieldTable, fieldName: fieldName});
|
||||
fieldNames.push(columns.columns[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
function renderOneGroupBy(groupBy: PivotTableGroupBy, index: number, rowsOrColumns: "rows" | "columns")
|
||||
{
|
||||
if(!isEditable)
|
||||
{
|
||||
const selectedField = getSelectedFieldForAutoComplete(groupBy.fieldName);
|
||||
if(selectedField)
|
||||
{
|
||||
const label = selectedField.table.name == tableMetaData.name ? selectedField.field.label : selectedField.table.label + ": " + selectedField.field.label
|
||||
return (<Box mr="0.375rem" mb="0.5rem" border={`1px solid ${colors.grayLines.main}`} borderRadius="0.75rem" p="0.25rem 0.75rem">{label}</Box>);
|
||||
}
|
||||
|
||||
return (<React.Fragment />);
|
||||
}
|
||||
|
||||
const handleFieldChange = (event: any, newValue: any, reason: string) =>
|
||||
{
|
||||
groupBy.fieldName = newValue ? newValue.fieldName : null;
|
||||
onSaveCallback({pivotTableJson: JSON.stringify(pivotTableDefinition)});
|
||||
updateUsedGroupByFieldNames();
|
||||
};
|
||||
|
||||
// maybe cursor:grab (and then change to "grabbing")
|
||||
return (<Box display="flex" p="0.5rem" pl="0" gap="0.5rem" alignItems="center">
|
||||
<Box>
|
||||
<Icon sx={{cursor: "ns-resize"}}>drag_indicator</Icon>
|
||||
</Box>
|
||||
<Box width="100%">
|
||||
<FieldAutoComplete
|
||||
id={`${rowsOrColumns}-${index}`}
|
||||
label={null}
|
||||
variant="outlined"
|
||||
textFieldSX={fieldAutoCompleteTextFieldSX}
|
||||
metaData={metaData}
|
||||
tableMetaData={tableMetaData}
|
||||
handleFieldChange={handleFieldChange}
|
||||
hiddenFieldNames={usedGroupByFieldNames}
|
||||
defaultValue={getSelectedFieldForAutoComplete(groupBy.fieldName)}
|
||||
/>
|
||||
</Box>
|
||||
<Box>
|
||||
<Button sx={xIconButtonSX} onClick={() => removeGroupBy(index, rowsOrColumns)}><Icon>clear</Icon></Button>
|
||||
</Box>
|
||||
</Box>);
|
||||
setAvailableFieldNames(fieldNames);
|
||||
}
|
||||
|
||||
|
||||
@ -409,12 +360,12 @@ export default function PivotTableSetupWidget({isEditable, widgetMetaData, recor
|
||||
*******************************************************************************/
|
||||
function renderOneValue(value: PivotTableValue, index: number)
|
||||
{
|
||||
if(!isEditable)
|
||||
if (!isEditable)
|
||||
{
|
||||
const selectedField = getSelectedFieldForAutoComplete(value.fieldName);
|
||||
if(selectedField && value.function)
|
||||
const selectedField = getSelectedFieldForAutoComplete(tableMetaData, value.fieldName);
|
||||
if (selectedField && value.function)
|
||||
{
|
||||
const label = selectedField.table.name == tableMetaData.name ? selectedField.field.label : selectedField.table.label + ": " + selectedField.field.label
|
||||
const label = selectedField.table.name == tableMetaData.name ? selectedField.field.label : selectedField.table.label + ": " + selectedField.field.label;
|
||||
return (<Box mr="0.375rem" mb="0.5rem" border={`1px solid ${colors.grayLines.main}`} borderRadius="0.75rem" p="0.25rem 0.75rem">{pivotTableFunctionLabels[value.function]} of {label}</Box>);
|
||||
}
|
||||
|
||||
@ -441,8 +392,8 @@ export default function PivotTableSetupWidget({isEditable, widgetMetaData, recor
|
||||
const label = "" + pivotTableFunctionLabels[pivotTableFunctionKey];
|
||||
const option = {id: pivotTableFunctionKey, label: label};
|
||||
functionOptions.push(option);
|
||||
|
||||
if(option.id == value.function)
|
||||
|
||||
if (option.id == value.function)
|
||||
{
|
||||
defaultFunctionValue = option;
|
||||
}
|
||||
@ -462,7 +413,7 @@ export default function PivotTableSetupWidget({isEditable, widgetMetaData, recor
|
||||
metaData={metaData}
|
||||
tableMetaData={tableMetaData}
|
||||
handleFieldChange={handleFieldChange}
|
||||
defaultValue={getSelectedFieldForAutoComplete(value.fieldName)}
|
||||
defaultValue={getSelectedFieldForAutoComplete(tableMetaData, value.fieldName)}
|
||||
/>
|
||||
</Box>
|
||||
<Box width="330px">
|
||||
@ -490,6 +441,36 @@ export default function PivotTableSetupWidget({isEditable, widgetMetaData, recor
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** drag & drop callback to move one of the pivot-table group-bys (rows/columns)
|
||||
*******************************************************************************/
|
||||
const moveGroupBy = useCallback((rowsOrColumns: "rows" | "columns", dragIndex: number, hoverIndex: number) =>
|
||||
{
|
||||
const array = pivotTableDefinition[rowsOrColumns];
|
||||
const dragItem = array[dragIndex];
|
||||
array.splice(dragIndex, 1);
|
||||
array.splice(hoverIndex, 0, dragItem);
|
||||
|
||||
onSaveCallback({pivotTableJson: JSON.stringify(pivotTableDefinition)});
|
||||
forceUpdate();
|
||||
}, [pivotTableDefinition]);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** drag & drop callback to move one of the pivot-table values
|
||||
*******************************************************************************/
|
||||
const moveValue = useCallback((dragIndex: number, hoverIndex: number) =>
|
||||
{
|
||||
const array = pivotTableDefinition.values;
|
||||
const dragItem = array[dragIndex];
|
||||
array.splice(dragIndex, 1);
|
||||
array.splice(hoverIndex, 0, dragItem);
|
||||
|
||||
onSaveCallback({pivotTableJson: JSON.stringify(pivotTableDefinition)});
|
||||
forceUpdate();
|
||||
}, [pivotTableDefinition]);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// add toggle component to widget header for editable mode //
|
||||
/////////////////////////////////////////////////////////////
|
||||
@ -501,19 +482,77 @@ export default function PivotTableSetupWidget({isEditable, widgetMetaData, recor
|
||||
|
||||
const selectTableFirstTooltipTitle = tableMetaData ? null : "You must select a table before you can set up a pivot table";
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** render a group-by (row or column)
|
||||
*******************************************************************************/
|
||||
const renderGroupBy = useCallback(
|
||||
(groupBy: PivotTableGroupBy, rowsOrColumns: "rows" | "columns", index: number) =>
|
||||
{
|
||||
return (
|
||||
<PivotTableGroupByElement
|
||||
key={groupBy.fieldName}
|
||||
index={index}
|
||||
id={`${groupBy.key}`}
|
||||
dragCallback={moveGroupBy}
|
||||
metaData={metaData}
|
||||
tableMetaData={tableMetaData}
|
||||
pivotTableDefinition={pivotTableDefinition}
|
||||
usedGroupByFieldNames={usedGroupByFieldNames}
|
||||
availableFieldNames={availableFieldNames}
|
||||
isEditable={isEditable}
|
||||
groupBy={groupBy}
|
||||
rowsOrColumns={rowsOrColumns}
|
||||
callback={groupByChangedCallback}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[tableMetaData, usedGroupByFieldNames, availableFieldNames],
|
||||
);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** render a pivot-table value (row or column)
|
||||
*******************************************************************************/
|
||||
const renderValue = useCallback(
|
||||
(value: PivotTableValue, index: number) =>
|
||||
{
|
||||
return (
|
||||
<PivotTableValueElement
|
||||
key={value.key}
|
||||
index={index}
|
||||
id={`${value.key}`}
|
||||
dragCallback={moveValue}
|
||||
metaData={metaData}
|
||||
tableMetaData={tableMetaData}
|
||||
pivotTableDefinition={pivotTableDefinition}
|
||||
availableFieldNames={availableFieldNames}
|
||||
isEditable={isEditable}
|
||||
value={value}
|
||||
callback={groupByChangedCallback}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[tableMetaData, usedGroupByFieldNames, availableFieldNames],
|
||||
);
|
||||
|
||||
|
||||
return (<Widget widgetMetaData={widgetMetaData} labelAdditionalElementsRight={labelAdditionalElementsRight}>
|
||||
{enabled && pivotTableDefinition &&
|
||||
<React.Fragment>
|
||||
<Grid container spacing="16" >
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
{
|
||||
showHelp("sectionSubhead") &&
|
||||
<Box color={colors.gray.main} pb={"0.5rem"} fontSize={"0.875rem"}>
|
||||
{getHelpContent("sectionSubhead")}
|
||||
</Box>
|
||||
}
|
||||
<Grid container spacing="16">
|
||||
|
||||
<Grid item lg={4} md={6} xs={12}>
|
||||
<h5>Rows</h5>
|
||||
<Box fontSize="1rem">
|
||||
{
|
||||
tableMetaData && pivotTableDefinition.rows?.map((row: PivotTableGroupBy, index: number) =>
|
||||
(
|
||||
<React.Fragment key={row.key}>{renderOneGroupBy(row, index, "rows")}</React.Fragment>
|
||||
))
|
||||
tableMetaData && (<div>{pivotTableDefinition?.rows?.map((row, i) => renderGroupBy(row, "rows", i))}</div>)
|
||||
}
|
||||
</Box>
|
||||
{
|
||||
@ -530,10 +569,7 @@ export default function PivotTableSetupWidget({isEditable, widgetMetaData, recor
|
||||
<h5>Columns</h5>
|
||||
<Box fontSize="1rem">
|
||||
{
|
||||
tableMetaData && pivotTableDefinition.columns?.map((column: PivotTableGroupBy, index: number) =>
|
||||
(
|
||||
<React.Fragment key={column.key}>{renderOneGroupBy(column, index, "columns")}</React.Fragment>
|
||||
))
|
||||
tableMetaData && (<div>{pivotTableDefinition?.columns?.map((column, i) => renderGroupBy(column, "columns", i))}</div>)
|
||||
}
|
||||
</Box>
|
||||
{
|
||||
@ -550,10 +586,7 @@ export default function PivotTableSetupWidget({isEditable, widgetMetaData, recor
|
||||
<h5>Values</h5>
|
||||
<Box fontSize="1rem">
|
||||
{
|
||||
tableMetaData && pivotTableDefinition.values?.map((value: PivotTableValue, index: number) =>
|
||||
(
|
||||
<React.Fragment key={value.key}>{renderOneValue(value, index)}</React.Fragment>
|
||||
))
|
||||
tableMetaData && (<div>{pivotTableDefinition?.values?.map((value, i) => renderValue(value, i))}</div>)
|
||||
}
|
||||
</Box>
|
||||
{
|
||||
@ -567,7 +600,44 @@ export default function PivotTableSetupWidget({isEditable, widgetMetaData, recor
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
{/*
|
||||
<Box mt={"1rem"}>
|
||||
<h5>Preview</h5>
|
||||
<table>
|
||||
<tr>
|
||||
<th style={{textAlign: "left", fontSize: "0.875rem"}}></th>
|
||||
<th style={{textAlign: "left", fontSize: "0.875rem"}}>Column Labels</th>
|
||||
</tr>
|
||||
{
|
||||
pivotTableDefinition?.columns?.map((column, i) =>
|
||||
(
|
||||
<tr key={column.key}>
|
||||
<th style={{textAlign: "left", fontSize: "0.875rem"}}></th>
|
||||
<th style={{textAlign: "left", fontSize: "0.875rem"}}>{column.fieldName}</th>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
<tr>
|
||||
<th style={{textAlign: "left", fontSize: "0.875rem"}}>Row Labels</th>
|
||||
{
|
||||
pivotTableDefinition?.values?.map((value, i) =>
|
||||
(
|
||||
<th key={value.key} style={{textAlign: "left", fontSize: "0.875rem"}}>{value.function} of {value.fieldName}</th>
|
||||
))
|
||||
}
|
||||
</tr>
|
||||
{
|
||||
pivotTableDefinition?.rows?.map((row, i) =>
|
||||
(
|
||||
<tr key={row.key}>
|
||||
<th style={{textAlign: "left", fontSize: "0.875rem", paddingLeft: (i * 1) + "rem"}}>{row.fieldName}</th>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
</table>
|
||||
</Box>
|
||||
*/}
|
||||
</DndProvider>
|
||||
}
|
||||
</Widget>);
|
||||
}
|
||||
|
Reference in New Issue
Block a user