Skip to content

Commit

Permalink
182089941 add log strings (Part 1) (#1385)
Browse files Browse the repository at this point in the history
* Adds uuid library for session key in logging

Initial commit of event logging

* Logs component title change, create or show component, component closed
Adds document metadata to document model properties
Log message now has document title as activity property value.

* Clean up some of the changes for getting document title from V2 documents to Logger.

* removes metadata property from document model since we are storing that information in `properties` prop

* Clean up logger code. Adds a error catcher when logger is not initialized.

Fixes logger jest tests and skips some of them.

Adds xhr-mock for jest test.

Temporarily removes logger.debug.test

* Adds log string to calculator

* Adds console log of string sent to log server

* Adds event_value prop to the log.

Adds log to some case table actions

* Uses the new implemention of sending log messages throught the model.applyModelChanges

* Adds `event-value` to the log props

* Change incorrect model to apply changes to for logging

* Adds logs to graph parent visibility and show measures toggle

Adds logs for graph background and point color change

* Removes uuid library

* Adds logging for graph adornment checkbox

Adds logging for graph  adornments:
movable point adornment, movable value, plotted function formula

* Removes uuid

Adds undo/redo to cases expand/collapse cases

Move graph transparency and background color apply model change to the point format palette

Fixes logic for logging parent toggle and measures for selection

* Removed unused logger types

* Changes the ILogMessage type

* Changes  log `event_value` to string, and `parameters` to Record <string, unknown>

Adds use logging context to be able to pass info from one component to another for logging.

Moves logging for plotted function from plotted-function-formula-adapter to plotted-function-adornment-banner

Moves logging cell edits from cell-text-editor to use-rows

Changes logging `args` to keys: string[], and values: unknown[]

* Removes logging for cell text changes until further investigation

* Clean up merge errors in attribute-menu-list

* Remove logging from plotted function formula adapter

Update ILogMessage type to use object instead arrays of keys and values

* chore: code review suggestions

---------

Co-authored-by: Kirk Swenson <[email protected]>
  • Loading branch information
eireland and kswenson authored Aug 14, 2024
1 parent 5f69882 commit c87608a
Show file tree
Hide file tree
Showing 26 changed files with 220 additions and 77 deletions.
8 changes: 7 additions & 1 deletion v3/src/components/calculator/calculator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ export const CalculatorComponent = ({ tile }: ITileBaseProps) => {
const clearValue = () => {
setCalcValue("")
setJustEvaled(false)
calculatorModel?.applyModelChange(() => {}, {
log: "Calculator value cleared"
})
}

const insert = (strToInsert: string) => {
Expand All @@ -39,6 +42,9 @@ export const CalculatorComponent = ({ tile }: ITileBaseProps) => {
try {
const solution = evaluate(calcValue)
!isNaN(solution) && setCalcValue(solution)
calculatorModel?.applyModelChange(() => {}, {
log: `Calculation done: ${calcValue} = ${solution}`
})
} catch (error) {
setCalcValue(`Error`)
}
Expand Down Expand Up @@ -84,7 +90,7 @@ export const CalculatorComponent = ({ tile }: ITileBaseProps) => {
<Text className="calc-input" data-testid="calc-input">{calcValue}</Text>
<Flex className="calc-buttons">
{calcButtons}
<Button className="calc-button wide" onClick={handleEvaluateButtonPress}
<Button className="calc-button wide" onClick={handleEvaluateButtonPress}
data-testid="calc-button">
=
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export const CaseTableCardTitleBar =
documentContent?.applyModelChange(() => {
tile && documentContent && toggleCardTable(documentContent, tile.id)
}, {
log: `Toggle component: ${suffix}`,
undoStringKey: `DG.Undo.component.toggle${suffix}`,
redoStringKey: `DG.Redo.component.toggle${suffix}`
})
Expand Down
48 changes: 31 additions & 17 deletions v3/src/components/case-table/attribute-menu/attribute-menu-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const AttributeMenuListComp = forwardRef<HTMLDivElement, IProps>(
const formulaModal = useDisclosure()
const attributeId = column.key
const attribute = data?.getAttribute(attributeId)
// const attributeName = attribute?.name
const collection = data?.getCollectionForAttribute(attributeId)

const handleEditPropertiesOpen = () => {
Expand All @@ -52,35 +53,46 @@ const AttributeMenuListComp = forwardRef<HTMLDivElement, IProps>(
onModalOpen(false)
}

// const handleSortCases = (item: IMenuItem) => {
// data?.applyModelChange(() => {}, {
// log: { message:`Sort cases by attribute:`, args: { attributeId: attribute?.id, attribute: attributeName }}
// })
// }

const handleMenuKeyDown = (e: React.KeyboardEvent) => {
e.stopPropagation()
}

interface IMenuItem {
itemString: string
itemKey: string
// defaults to true if not implemented
isEnabled?: () => boolean
handleClick?: () => void
isEnabled?: (item: IMenuItem) => boolean
handleClick?: (item: IMenuItem) => void
}

const menuItems: IMenuItem[] = [
{
itemString: t("DG.TableController.headerMenuItems.renameAttribute"),
itemKey: "DG.TableController.headerMenuItems.renameAttribute",
handleClick: onRenameAttribute
},
{
itemString: t("DG.TableController.headerMenuItems.resizeColumn")
itemKey: "DG.TableController.headerMenuItems.resizeColumn",
// handleClick: () => {
// data?.applyModelChange(() => {}, {
// log: {message:`Fit column width:`, args: { collection: data?.name, attribute: attributeName }}
// })
// }
},
{
itemString: t("DG.TableController.headerMenuItems.editAttribute"),
itemKey: "DG.TableController.headerMenuItems.editAttribute",
handleClick: handleEditPropertiesOpen
},
{
itemString: t("DG.TableController.headerMenuItems.editFormula"),
itemKey: "DG.TableController.headerMenuItems.editFormula",
handleClick: handleEditFormulaOpen
},
{
itemString: t("DG.TableController.headerMenuItems.deleteFormula"),
itemKey: "DG.TableController.headerMenuItems.deleteFormula",
isEnabled: () => !!(attribute?.editable && attribute?.hasFormula),
handleClick: () => {
data?.applyModelChange(() => {
Expand All @@ -93,10 +105,10 @@ const AttributeMenuListComp = forwardRef<HTMLDivElement, IProps>(
}
},
{
itemString: t("DG.TableController.headerMenuItems.recoverFormula")
itemKey: "DG.TableController.headerMenuItems.recoverFormula"
},
{
itemString: t("DG.TableController.headerMenuItems.randomizeAttribute"),
itemKey: "DG.TableController.headerMenuItems.randomizeAttribute",
isEnabled: () => !!attribute?.formula?.isRandomFunctionPresent,
handleClick: () => {
data?.applyModelChange(() => {
Expand All @@ -105,13 +117,15 @@ const AttributeMenuListComp = forwardRef<HTMLDivElement, IProps>(
}
},
{
itemString: t("DG.TableController.headerMenuItems.sortAscending")
itemKey: "DG.TableController.headerMenuItems.sortAscending",
// handleClick: handleSortCases
},
{
itemString: t("DG.TableController.headerMenuItems.sortDescending")
itemKey: "DG.TableController.headerMenuItems.sortDescending",
// handleClick: handleSortCases
},
{
itemString: t("DG.TableController.headerMenuItems.hideAttribute"),
itemKey: "DG.TableController.headerMenuItems.hideAttribute",
isEnabled: () => {
// can't hide last attribute of collection
const visibleAttributes = collection?.attributes
Expand All @@ -132,7 +146,7 @@ const AttributeMenuListComp = forwardRef<HTMLDivElement, IProps>(
}
},
{
itemString: t("DG.TableController.headerMenuItems.deleteAttribute"),
itemKey: "DG.TableController.headerMenuItems.deleteAttribute",
isEnabled: () => {
if (!data) return false

Expand Down Expand Up @@ -173,15 +187,15 @@ const AttributeMenuListComp = forwardRef<HTMLDivElement, IProps>(
function isItemEnabled(item: IMenuItem) {
if (!item.handleClick) return false
if (!item.isEnabled) return true
return item.isEnabled()
return item.isEnabled(item)
}

return (
<>
<MenuList ref={ref} data-testid="attribute-menu-list" onKeyDown={handleMenuKeyDown}>
{menuItems.map(item => (
<MenuItem key={item.itemString} isDisabled={!isItemEnabled(item)} onClick={item.handleClick}>
{`${item.itemString}${item.handleClick ? "" : " 🚧"}`}
<MenuItem key={item.itemKey} isDisabled={!isItemEnabled(item)} onClick={() => item.handleClick?.(item)}>
{`${t(item.itemKey)}${item.handleClick ? "" : " 🚧"}`}
</MenuItem>
))}
</MenuList>
Expand Down
9 changes: 8 additions & 1 deletion v3/src/components/case-table/case-table-inspector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ export const CaseTableInspector = ({ tile, show }: ITileInspectorPanelProps) =>
switch (tool) {
case "datasetInfo":
setShowInfoModal(true)
break
case "resizeColumns":
//TODO move log to respective handler
tableModel?.applyModelChange(() => {}, {
log: { message:`resizeColumns`, args: {dataContext: data?.name} }
})
break
}
}

Expand All @@ -42,7 +49,7 @@ export const CaseTableInspector = ({ tile, show }: ITileInspectorPanelProps) =>
<InformationIcon />
</InspectorButton>
<InspectorButton tooltip={t("DG.Inspector.resize.toolTip")} showMoreOptions={false}
testId="resize-table-button">
testId="resize-table-button" onButtonClick={()=>handleButtonClick("resizeColumns")}>
<ScaleDataIcon />
</InspectorButton>
<InspectorMenu tooltip={t("DG.Inspector.delete.toolTip")}
Expand Down
9 changes: 8 additions & 1 deletion v3/src/components/case-table/collection-table-spacer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,21 @@ export const CollectionTableSpacer = observer(function CollectionTableSpacer({ o
caseMetadata?.applyModelChange(() => {
parentCases?.forEach((value) => caseMetadata?.setIsCollapsed(value.__id__, !everyCaseIsCollapsed))
}, {
log: "Expand/Collapse all",
undoStringKey: "DG.Undo.caseTable.groupToggleExpandCollapseAll",
redoStringKey: "DG.Redo.caseTable.groupToggleExpandCollapseAll"
})
}

function handleExpandCollapseClick(parentCaseId: string) {
// collapse the parent case
caseMetadata?.setIsCollapsed(parentCaseId, !caseMetadata?.isCollapsed(parentCaseId))
caseMetadata?.applyModelChange(() => {
caseMetadata?.setIsCollapsed(parentCaseId, !caseMetadata?.isCollapsed(parentCaseId))
}, {
undoStringKey: "DG.Undo.caseTable.expandCollapseOneCase",
redoStringKey: "DG.Redo.caseTable.expandCollapseOneCase",
log: `${caseMetadata?.isCollapsed(parentCaseId) ? "Collapse" : "Expand"} case ${parentCaseId}`
})
// scroll to the first expanded/collapsed child case (if necessary)
const parentCase = data?.caseInfoMap.get(parentCaseId)
const firstChildId = parentCase?.childCaseIds?.[0] || parentCase?.childItemIds?.[0]
Expand Down
1 change: 1 addition & 0 deletions v3/src/components/case-table/collection-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export const CollectionTable = observer(function CollectionTable(props: IProps)
caseTableModel?.applyModelChange(() => {
caseTableModel?.columnWidths.set(attrId, width)
}, {
log: "Resize one case table column",
undoStringKey: "DG.Undo.caseTable.resizeOneColumn",
redoStringKey: "DG.Redo.caseTable.resizeOneColumn"
})
Expand Down
1 change: 1 addition & 0 deletions v3/src/components/case-table/insert-cases-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const InsertCasesModal: React.FC<IProps> =
data?.applyModelChange(() => {
data.addCases(casesToAdd, {[insertPosition]: caseId})
}, {
log: `insert ${numCasesToInsert} cases in table`,
undoStringKey: "DG.Undo.caseTable.insertCases",
redoStringKey: "DG.Redo.caseTable.insertCases"
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,48 +15,58 @@ interface IProps {
displayItemDescription: IDisplayItemDescriptionModel
pointDisplayType?: string
isTransparent?: boolean
setIsTransparent?: (isTransparent: boolean) => void
onBackgroundTransparencyChange?: (isTransparent: boolean) => void
plotBackgroundColor?: string
setPlotBackgroundColor?: (color: string) => void
onBackgroundColorChange?: (color: string) => void
}

export const DisplayItemFormatControl = observer(function PointFormatControl(props: IProps) {
const {
dataConfiguration, displayItemDescription, pointDisplayType,
isTransparent, setIsTransparent, plotBackgroundColor, setPlotBackgroundColor
isTransparent, onBackgroundTransparencyChange, plotBackgroundColor, onBackgroundColorChange
} = props
const legendAttrID = dataConfiguration.attributeID("legend")
const attrType = dataConfiguration?.dataset?.attrFromID(legendAttrID ?? "")?.type
const categoriesRef = useRef<string[] | undefined>()
categoriesRef.current = dataConfiguration?.categoryArrayForAttrRole('legend')

const handlePointColorChange = (color: string) => {
displayItemDescription.applyModelChange(() => {
displayItemDescription.setPointColor(color)
}, {
undoStringKey: "DG.Undo.graph.changePointColor",
redoStringKey: "DG.Redo.graph.changePointColor",
log: "Changed point color"
})
}

const catPointColorSettingArr: ReactElement[] = []
categoriesRef.current?.forEach(cat => {
catPointColorSettingArr.push(
<Flex direction="row" key={cat} className="palette-row color-picker-row cat-color-picker">
<FormLabel className="form-label color-picker">{cat}</FormLabel>
<Input type="color" className="color-picker-thumb categorical"
value={dataConfiguration?.getLegendColorForCategory(cat) || missingColor}
onChange={e => displayItemDescription.setPointColor(e.target.value)}/>
onChange={e => handlePointColorChange(e.target.value)}/>
</Flex>
)
})

const renderPlotControlsIfAny = () => {
if (setIsTransparent && setPlotBackgroundColor) {
if (onBackgroundTransparencyChange && onBackgroundColorChange) {
return (
<div>
<FormControl isDisabled={isTransparent}>
<Flex className="palette-row color-picker-row">
<FormLabel className="form-label color-picker">{t("DG.Inspector.backgroundColor")}</FormLabel>
<Input type="color" className="color-picker-thumb" value={plotBackgroundColor}
onChange={e => setPlotBackgroundColor(e.target.value)}/>
onChange={e => onBackgroundColorChange(e.target.value)}/>
</Flex>
</FormControl>
<FormControl>
<Checkbox
mt="6px" isChecked={isTransparent}
onChange={e => setIsTransparent(e.target.checked)}>
onChange={e => onBackgroundTransparencyChange(e.target.checked)}>
{t("DG.Inspector.graphTransparency")}
</Checkbox>
</FormControl>
Expand Down
6 changes: 4 additions & 2 deletions v3/src/components/graph/adornments/adornment-checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,17 @@ export const AdornmentCheckbox = observer(function AdornmentCheckbox({classNameV
() => adornmentsStore.addAdornment(adornment, graphModel.getUpdateCategoriesOptions()),
{
undoStringKey: undoRedoKeys.undoAdd,
redoStringKey: undoRedoKeys.redoAdd
redoStringKey: undoRedoKeys.redoAdd,
log: `Added ${adornment.type}`
}
)
} else {
graphModel.applyModelChange(
() => adornmentsStore.hideAdornment(adornment.type),
{
undoStringKey: undoRedoKeys.undoRemove,
redoStringKey: undoRedoKeys.redoRemove
redoStringKey: undoRedoKeys.redoRemove,
log: `Removed ${adornment.type}`
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const MovablePointAdornment = observer(function MovablePointAdornment(pro
const { xSubAxesCount, ySubAxesCount } = useAdornmentCategories()
const pointRef = useRef<SVGGElement | null>(null)
const [pointObject, setPointObject] = useState<IPointObject>({})
const dragStartPoint = useRef({x: 0, y: 0})

// Set up refs for determining when attributes have changed and the point needs to be reset
// to the initial position
Expand Down Expand Up @@ -62,6 +63,12 @@ export const MovablePointAdornment = observer(function MovablePointAdornment(pro
.attr('cy', yPoint + 1)
}, [pointObject.point, pointObject.shadow])

const handleDragStart = useCallback((event: MouseEvent) => {
const { x: xPoint, y: yPoint } = event
dragStartPoint.current = {x: Math.round(xScale.invert(xPoint * xSubAxesCount)*10)/10,
y: Math.round(yScale.invert(yPoint * ySubAxesCount)*10)/10}
}, [xScale, xSubAxesCount, yScale, ySubAxesCount])

const handleDrag = useCallback((event: MouseEvent) => {
const { x: xPoint, y: yPoint } = event
// don't allow point to be dragged outside plot area
Expand All @@ -87,7 +94,8 @@ export const MovablePointAdornment = observer(function MovablePointAdornment(pro
() => model.setPoint({x: xValue, y: yValue}, instanceKey),
{
undoStringKey: "DG.Undo.graph.moveMovablePoint",
redoStringKey: "DG.Redo.graph.moveMovablePoint"
redoStringKey: "DG.Redo.graph.moveMovablePoint",
log: `Move point from (${dragStartPoint.current.x}, ${dragStartPoint.current.y} to (${xValue}, ${yValue})`
}
)

Expand Down Expand Up @@ -120,10 +128,11 @@ export const MovablePointAdornment = observer(function MovablePointAdornment(pro
.call(dataTip)
.call(
drag<SVGCircleElement, unknown>()
.on("start", handleDragStart)
.on("drag", handleDrag)
.on("end", handleDragEnd)
)
}, [pointObject, handleDrag, handleDragEnd, showCoordinates, hideCoordinates])
}, [pointObject, handleDrag, handleDragEnd, showCoordinates, hideCoordinates, handleDragStart])

// Set up the point and shadow
useEffect(function createElements() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,12 @@ export const MovableValueAdornment = observer(function MovableValueAdornment(pro
() => model.endDrag(dragValue, instanceKey, dragIndex),
{
undoStringKey: "DG.Undo.graph.moveMovableValue",
redoStringKey: "DG.Redo.graph.moveMovableValue"
redoStringKey: "DG.Redo.graph.moveMovableValue",
log: `Moved value from ${
model.values.get(instanceKey)?.[dragIndex] !== undefined
? Math.round(model.values.get(instanceKey)![dragIndex] * 10) / 10
: 'undefined'
} to ${Math.round(dragValue *10)/10}`
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ const Controls = () => {
() => adornmentsStore.addAdornment(adornment, graphModel.getUpdateCategoriesOptions()),
{
undoStringKey: kMovableValueUndoAddKey,
redoStringKey: kMovableValueRedoAddKey
redoStringKey: kMovableValueRedoAddKey,
log: `Added movable value`
}
)
}
Expand All @@ -38,7 +39,8 @@ const Controls = () => {
},
{
undoStringKey: kMovableValueUndoRemoveKey,
redoStringKey: kMovableValueRedoRemoveKey
redoStringKey: kMovableValueRedoRemoveKey,
log: `Removed movable value`
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ export const PlottedFunctionAdornmentBanner = observer(function PlottedFunctionA
() => model.setExpression(newExpression),
{
undoStringKey: "DG.Undo.graph.changePlotFunction",
redoStringKey: "DG.Redo.graph.changePlotFunction"
redoStringKey: "DG.Redo.graph.changePlotFunction",
log: { message: "Change plotted function", args: {from: expression, to: newExpression}}
}
)
}
Expand Down
Loading

0 comments on commit c87608a

Please sign in to comment.