From 72760008c48c1e0c4c2af0ac2db230effd5aae1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20B=C3=A9gaudeau?= Date: Mon, 6 Jan 2025 09:58:59 +0100 Subject: [PATCH 1/2] [cleanup] Make sirius-components-charts use the strict version of our TypeScript configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Bégaudeau --- CHANGELOG.adoc | 1 + .../src/bar/BarChart.tsx | 21 ++++++++++--------- .../sirius-components-charts/tsconfig.json | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 5cb2cf6fa4..a1db4c2a75 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -41,6 +41,7 @@ Specifiers can contribute dedicated AQL services for this feature using implemen === Improvements - https://github.com/eclipse-sirius/sirius-web/issues/4368[#4368] [sirius-web] Add GraphQL subscription exception handler +- [charts] Make the npm package `sirius-components-charts` use the strict version of our TypeScript configuration == v2025.1.0 diff --git a/packages/charts/frontend/sirius-components-charts/src/bar/BarChart.tsx b/packages/charts/frontend/sirius-components-charts/src/bar/BarChart.tsx index 289dd3409f..36004ab763 100644 --- a/packages/charts/frontend/sirius-components-charts/src/bar/BarChart.tsx +++ b/packages/charts/frontend/sirius-components-charts/src/bar/BarChart.tsx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022, 2024 Obeo. + * Copyright (c) 2022, 2025 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -13,7 +13,7 @@ import * as d3 from 'd3'; import { useEffect, useRef } from 'react'; import { getFontSize, getFontStyle, getFontWeight, getTextDecoration } from '../chartOperations'; -import { BarChartProps } from './BarChart.types'; +import { BarChartProps, BarChartRepresentationEntry } from './BarChart.types'; const marginTop = 30; const marginBottom = 30; @@ -22,8 +22,9 @@ const marginLeft = 50; const xPadding = 0.1; const yType = d3.scaleLinear; const yFormat = 'f'; -const x = (d) => d.key; -const y = (d) => d.value; + +const x = (entry: BarChartRepresentationEntry) => entry.key; +const y = (entry: BarChartRepresentationEntry) => entry.value; export const BarChart = ({ chart }: BarChartProps) => { const d3Container = useRef(null); @@ -52,10 +53,10 @@ export const BarChart = ({ chart }: BarChartProps) => { // Compute default domains, and unique the x-domain. const xDomain = new d3.InternSet(X); - const yDomain = [0, d3.max(Y)]; + const yDomain = [0, d3.max(Y) ?? 0]; // Omit any data not present in the x-domain. - const I = d3.range(X.length).filter((i) => xDomain.has(X[i])); + const I = d3.range(X.length).filter((i) => X[i] && xDomain.has(X[i] ?? '')); // Construct scales, axes, and formats. const xScale = d3.scaleBand(xDomain, xRange).padding(xPadding); @@ -65,7 +66,7 @@ export const BarChart = ({ chart }: BarChartProps) => { // Compute titles. const formatValue = yScale.tickFormat(100, yFormat); - const title = (i) => `${X[i]}\n${formatValue(Y[i])}`; + const title = (index: number) => `${X[index]}\n${formatValue(Y[index] ?? 0)}`; const selection = d3.select(d3Container.current); selection.selectAll('*').remove(); // Remove existing content. @@ -103,9 +104,9 @@ export const BarChart = ({ chart }: BarChartProps) => { .selectAll('rect') .data(I) .join('rect') - .attr('x', (i) => xScale(X[i])) - .attr('y', (i) => yScale(Y[i])) - .attr('height', (i) => yScale(0) - yScale(Y[i])) + .attr('x', (index: number) => xScale(X[index] ?? '') ?? '') + .attr('y', (index: number) => yScale(Y[index] ?? 0)) + .attr('height', (index: number) => yScale(0) - yScale(Y[index] ?? 0)) .attr('width', xScale.bandwidth()); if (title) { diff --git a/packages/charts/frontend/sirius-components-charts/tsconfig.json b/packages/charts/frontend/sirius-components-charts/tsconfig.json index e128174dd9..76330368e9 100644 --- a/packages/charts/frontend/sirius-components-charts/tsconfig.json +++ b/packages/charts/frontend/sirius-components-charts/tsconfig.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@eclipse-sirius/sirius-components-tsconfig/react-library.json", + "extends": "@eclipse-sirius/sirius-components-tsconfig/strict-react-library.json", "compilerOptions": { "emitDeclarationOnly": true, "outDir": "./dist" From ee080153794321b6fddf7931547cb97f7ca14aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20B=C3=A9gaudeau?= Date: Mon, 6 Jan 2025 10:30:25 +0100 Subject: [PATCH 2/2] [cleanup] Make sirius-components-trees use the strict version of our TypeScript configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Bégaudeau --- CHANGELOG.adoc | 1 + .../src/toolbar/TreeToolBar.tsx | 11 +++---- .../src/treeitems/TreeItem.tsx | 24 +++++++-------- .../src/treeitems/TreeItemAction.tsx | 10 +++---- .../src/treeitems/TreeItemDirectEditInput.tsx | 18 ++++++----- .../TreeItemDirectEditInput.types.ts | 4 +-- .../src/treeitems/filterTreeItem.ts | 6 ++-- .../src/trees/Tree.tsx | 30 ++++++++++--------- .../sirius-components-trees/tsconfig.json | 2 +- 9 files changed, 52 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index a1db4c2a75..d65431b7c9 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -42,6 +42,7 @@ Specifiers can contribute dedicated AQL services for this feature using implemen - https://github.com/eclipse-sirius/sirius-web/issues/4368[#4368] [sirius-web] Add GraphQL subscription exception handler - [charts] Make the npm package `sirius-components-charts` use the strict version of our TypeScript configuration +- [trees] Make the npm package `sirius-components-trees` use the strict version of our TypeScript configuration == v2025.1.0 diff --git a/packages/trees/frontend/sirius-components-trees/src/toolbar/TreeToolBar.tsx b/packages/trees/frontend/sirius-components-trees/src/toolbar/TreeToolBar.tsx index 31d9b4ea38..6aa3e67c05 100644 --- a/packages/trees/frontend/sirius-components-trees/src/toolbar/TreeToolBar.tsx +++ b/packages/trees/frontend/sirius-components-trees/src/toolbar/TreeToolBar.tsx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023, 2024 Obeo. + * Copyright (c) 2023, 2025 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -46,11 +46,6 @@ export const TreeToolBar = ({ }: TreeToolBarProps) => { const { classes } = useTreeToolbarStyles(); - let treeFiltersMenu: JSX.Element; - if (treeFilters.length > 0) { - treeFiltersMenu = ; - } - const preferenceButtonSynchronizeTitle = synchronized ? 'Disable synchronization with representation' : 'Enable synchronization with representation'; @@ -66,7 +61,9 @@ export const TreeToolBar = ({ const element = React.createElement(component, props); return element; })} - {treeFiltersMenu} + {treeFilters.length > 0 ? ( + + ) : null} {children} { - const { classes } = useTreeItemStyle({ depth }); - - const initialState: TreeItemState = { + const [state, setState] = useState({ editingMode: false, editingKey: null, partHovered: null, - }; - - const [state, setState] = useState(initialState); - const { editingMode } = state; + }); const refDom = useRef() as any; + const { classes } = useTreeItemStyle({ depth }); const { selection, setSelection } = useSelection(); const { onDropTreeItem } = useDropTreeItem(editingContextId, treeId); @@ -161,7 +157,7 @@ export const TreeItem = ({ })); }; - let content = null; + let content: JSX.Element | null = null; if (item.expanded && item.children) { content = (
    @@ -191,7 +187,7 @@ export const TreeItem = ({ } let className = classes.treeItem; - let dataTestid = undefined; + let dataTestid: string | undefined = undefined; const selected = selection.entries.find((entry) => entry.id === item.id); if (selected) { @@ -225,7 +221,7 @@ export const TreeItem = ({ }; const marked: boolean = markedItemIds.some((id) => id === item.id); - if (editingMode) { + if (state.editingMode) { text = ( ; @@ -277,7 +273,7 @@ export const TreeItem = ({ }; const onBeginEditing = (event) => { - if (!item.editable || editingMode || readOnly || !event.currentTarget.contains(event.target as HTMLElement)) { + if (!item.editable || state.editingMode || readOnly || !event.currentTarget.contains(event.target as HTMLElement)) { return; } const { key } = event; @@ -335,7 +331,7 @@ export const TreeItem = ({ const query = item.kind.substring(item.kind.indexOf('?') + 1, item.kind.length); const params = new URLSearchParams(query); if (params.has('type')) { - tooltipText = params.get('type'); + tooltipText = params.get('type') ?? 'representation'; } } diff --git a/packages/trees/frontend/sirius-components-trees/src/treeitems/TreeItemAction.tsx b/packages/trees/frontend/sirius-components-trees/src/treeitems/TreeItemAction.tsx index db9248a761..1c317a08c2 100644 --- a/packages/trees/frontend/sirius-components-trees/src/treeitems/TreeItemAction.tsx +++ b/packages/trees/frontend/sirius-components-trees/src/treeitems/TreeItemAction.tsx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 Obeo. + * Copyright (c) 2024, 2025 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,10 +10,10 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -import IconButton from '@mui/material/IconButton'; -import { makeStyles } from 'tss-react/mui'; import MoreVertIcon from '@mui/icons-material/MoreVert'; +import IconButton from '@mui/material/IconButton'; import { useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { getString } from './TreeItem'; import { TreeItemActionProps, TreeItemActionState } from './TreeItemAction.types'; import { TreeItemContextMenu } from './TreeItemContextMenu'; @@ -56,8 +56,8 @@ export const TreeItemAction = ({ } }; - let contextMenu = null; - if (state.showContextMenu) { + let contextMenu: JSX.Element | null = null; + if (state.showContextMenu && state.menuAnchor) { const closeContextMenu = () => { setState((prevState) => ({ ...prevState, diff --git a/packages/trees/frontend/sirius-components-trees/src/treeitems/TreeItemDirectEditInput.tsx b/packages/trees/frontend/sirius-components-trees/src/treeitems/TreeItemDirectEditInput.tsx index add60dbba3..51cbf12475 100644 --- a/packages/trees/frontend/sirius-components-trees/src/treeitems/TreeItemDirectEditInput.tsx +++ b/packages/trees/frontend/sirius-components-trees/src/treeitems/TreeItemDirectEditInput.tsx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023, 2024 Obeo. + * Copyright (c) 2023, 2025 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -85,24 +85,26 @@ export const TreeItemDirectEditInput = ({ }); useEffect(() => { - let cleanup = undefined; if (initialLabelTreeItemItemError) { addErrorMessage('An unexpected error has occurred, please refresh the page'); } - if (initialLabelTreeItemItemData?.viewer.editingContext.representation.description.initialDirectEditTreeItemLabel) { - const initialLabel = - initialLabelTreeItemItemData?.viewer.editingContext.representation.description.initialDirectEditTreeItemLabel; + const initialLabel = + initialLabelTreeItemItemData?.viewer.editingContext.representation.description.initialDirectEditTreeItemLabel; + if (initialLabel) { if (!editingKey) { setState((prevState) => { return { ...prevState, newLabel: initialLabel }; }); const timeOutId = setTimeout(() => { - textInput.current.select(); + if (textInput.current) { + textInput.current.select(); + } }, 0); - cleanup = () => clearTimeout(timeOutId); + + return () => clearTimeout(timeOutId); } } - return cleanup; + return () => {}; }, [initialLabelTreeItemItemError, initialLabelTreeItemItemData]); const [renameTreeItem, { data: renameTreeItemData, error: renameTreeItemError }] = diff --git a/packages/trees/frontend/sirius-components-trees/src/treeitems/TreeItemDirectEditInput.types.ts b/packages/trees/frontend/sirius-components-trees/src/treeitems/TreeItemDirectEditInput.types.ts index 3d2d542d14..e3fcbae8b1 100644 --- a/packages/trees/frontend/sirius-components-trees/src/treeitems/TreeItemDirectEditInput.types.ts +++ b/packages/trees/frontend/sirius-components-trees/src/treeitems/TreeItemDirectEditInput.types.ts @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023, 2024 Obeo. + * Copyright (c) 2023, 2025 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -15,7 +15,7 @@ export interface TreeItemDirectEditInputProps { editingContextId: string; treeId: string; treeItemId: string; - editingKey: string; + editingKey: string | null; onClose: () => void; } diff --git a/packages/trees/frontend/sirius-components-trees/src/treeitems/filterTreeItem.ts b/packages/trees/frontend/sirius-components-trees/src/treeitems/filterTreeItem.ts index d7c0768f58..43e0b5e3f0 100644 --- a/packages/trees/frontend/sirius-components-trees/src/treeitems/filterTreeItem.ts +++ b/packages/trees/frontend/sirius-components-trees/src/treeitems/filterTreeItem.ts @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023, 2024 Obeo. + * Copyright (c) 2023, 2025 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -22,12 +22,12 @@ export const isFilterCandidate = (treeItem: GQLTreeItem, textToFilter: string | filter = false; } else if ( !treeItem.hasChildren && - splitLabelWithTextToHighlight.length === 1 && + splitLabelWithTextToHighlight[0] && splitLabelWithTextToHighlight[0].toLocaleLowerCase() !== textToFilter.toLocaleLowerCase() ) { filter = true; } else if ( - splitLabelWithTextToHighlight.length === 1 && + splitLabelWithTextToHighlight[0] && splitLabelWithTextToHighlight[0].toLocaleLowerCase() === textToFilter.toLocaleLowerCase() ) { filter = false; diff --git a/packages/trees/frontend/sirius-components-trees/src/trees/Tree.tsx b/packages/trees/frontend/sirius-components-trees/src/trees/Tree.tsx index cdce98dd75..14cfa8cc9e 100644 --- a/packages/trees/frontend/sirius-components-trees/src/trees/Tree.tsx +++ b/packages/trees/frontend/sirius-components-trees/src/trees/Tree.tsx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2024 Obeo. + * Copyright (c) 2019, 2025 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -36,7 +36,7 @@ export const Tree = ({ treeItemActionRender, }: TreeProps) => { const { classes } = useTreeStyle(); - const treeElement = useRef(null); + const treeElement = useRef(null); useEffect(() => { const downHandler = (event) => { @@ -50,42 +50,44 @@ export const Tree = ({ event.preventDefault(); const previousItem = document.activeElement as HTMLElement; - const dataset = (previousItem as any).dataset; + const dataset = previousItem.dataset; if (dataset.treeitemid) { const treeItemDomElements = document.querySelectorAll('[data-treeitemid]'); const index = Array.from(treeItemDomElements).indexOf(previousItem); const id = dataset.treeitemid; const hasChildren = dataset.haschildren === 'true'; const isExpanded = dataset.expanded === 'true'; + const depth: number = parseInt(dataset.depth ?? '0'); switch (event.key) { case 'ArrowLeft': if (hasChildren && isExpanded) { - onExpand(id, dataset.depth); + onExpand(id, depth); } else if (index > 0) { - const parentDepth = (dataset.depth - 1).toString(); - let positionFromParent = 0; - while (!(treeItemDomElements[index - positionFromParent].dataset.depth === parentDepth)) { + const parentDepth = (depth - 1).toString(); + + let positionFromParent: number = 0; + while (!(treeItemDomElements[index - positionFromParent]?.dataset.depth === parentDepth)) { positionFromParent++; } - treeItemDomElements[index - positionFromParent].click(); + treeItemDomElements[index - positionFromParent]?.click(); } break; case 'ArrowRight': if (hasChildren && !isExpanded) { - onExpand(id, dataset.depth); + onExpand(id, depth); } else if (index < treeItemDomElements.length - 1) { - treeItemDomElements[index + 1].click(); + treeItemDomElements[index + 1]?.click(); } break; case 'ArrowUp': if (index > 0) { - treeItemDomElements[index - 1].click(); + treeItemDomElements[index - 1]?.click(); } break; case 'ArrowDown': if (index < treeItemDomElements.length - 1) { - treeItemDomElements[index + 1].click(); + treeItemDomElements[index + 1]?.click(); } break; default: @@ -94,7 +96,7 @@ export const Tree = ({ } }; - const element = treeElement?.current; + const element = treeElement.current; if (element) { element.addEventListener('keydown', downHandler); @@ -102,7 +104,7 @@ export const Tree = ({ element.removeEventListener('keydown', downHandler); }; } - return null; + return () => {}; }, [treeElement, onExpand]); return ( diff --git a/packages/trees/frontend/sirius-components-trees/tsconfig.json b/packages/trees/frontend/sirius-components-trees/tsconfig.json index e128174dd9..76330368e9 100644 --- a/packages/trees/frontend/sirius-components-trees/tsconfig.json +++ b/packages/trees/frontend/sirius-components-trees/tsconfig.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@eclipse-sirius/sirius-components-tsconfig/react-library.json", + "extends": "@eclipse-sirius/sirius-components-tsconfig/strict-react-library.json", "compilerOptions": { "emitDeclarationOnly": true, "outDir": "./dist"