From 8f607c3ca0954f9bf5cf6552ad629c74212e3cf6 Mon Sep 17 00:00:00 2001 From: Dmitry Lavrinovich <52966626+dmlvr@users.noreply.github.com> Date: Thu, 8 Jan 2026 17:34:15 +0200 Subject: [PATCH] ASP Related: fix ts issues in demos in strict mode (#32122) --- .../Demos/Diagram/Adaptability/React/App.tsx | 6 ++-- .../Demos/Diagram/Adaptability/ReactJs/App.js | 6 ++-- .../Diagram/AdvancedDataBinding/React/App.tsx | 6 ++-- .../Demos/Diagram/Containers/React/App.tsx | 6 ++-- .../Demos/Diagram/Containers/ReactJs/App.js | 6 ++-- .../CustomShapesWithTemplates/React/App.tsx | 2 +- .../React/CustomShapeTemplate.tsx | 3 +- .../React/App.tsx | 32 +++++++++++++------ .../React/CustomShapeTemplate.tsx | 2 +- .../CustomShapesWithTexts/React/App.tsx | 6 ++-- .../CustomShapesWithTexts/ReactJs/App.js | 6 ++-- .../Demos/Diagram/ItemSelection/React/App.tsx | 7 ++-- .../Diagram/ItemSelection/ReactJs/App.js | 2 +- .../Demos/Diagram/Overview/React/App.tsx | 6 ++-- .../Demos/Diagram/Overview/ReactJs/App.js | 6 ++-- .../Demos/Diagram/ReadOnly/React/App.tsx | 4 +-- .../Demos/Diagram/ReadOnly/ReactJs/App.js | 4 +-- .../Diagram/UICustomization/React/App.tsx | 8 ++--- .../Diagram/UICustomization/ReactJs/App.js | 4 +-- .../FileManager/BindingToEF/React/App.tsx | 10 +++--- .../FileManager/BindingToEF/ReactJs/App.js | 3 +- .../CustomThumbnails/React/App.tsx | 7 +++- .../Demos/FileManager/Overview/React/App.tsx | 6 ++-- .../Demos/FileManager/Overview/ReactJs/App.js | 3 +- .../FileManager/UICustomization/React/App.tsx | 25 +++++++++------ .../FileManager/UICustomization/React/data.ts | 6 ++-- .../UICustomization/ReactJs/App.js | 20 ++++++------ .../TaskProgressTooltipContentTemplate.tsx | 2 +- .../Appearance/React/TaskTooltipTemplate.tsx | 4 +-- .../Demos/Gantt/ContextMenu/React/App.tsx | 3 +- .../Demos/Gantt/ExportToPDF/React/App.tsx | 21 +++++++++--- .../Demos/Gantt/ExportToPDF/ReactJs/App.js | 2 +- .../Gantt/TaskTemplate/React/TaskTemplate.tsx | 15 ++++++++- apps/demos/tsconfig.react-check.json | 6 ---- 34 files changed, 155 insertions(+), 100 deletions(-) diff --git a/apps/demos/Demos/Diagram/Adaptability/React/App.tsx b/apps/demos/Demos/Diagram/Adaptability/React/App.tsx index 8c952bb4d043..afedd115e99d 100644 --- a/apps/demos/Demos/Diagram/Adaptability/React/App.tsx +++ b/apps/demos/Demos/Diagram/Adaptability/React/App.tsx @@ -4,14 +4,14 @@ import type { DiagramRef } from 'devextreme-react/diagram'; import 'whatwg-fetch'; export default function App() { - const diagramRef = useRef(); + const diagramRef = useRef(null); useEffect(() => { - const diagram = diagramRef.current.instance(); + const diagram = diagramRef?.current?.instance(); fetch('../../../../data/diagram-flow.json') .then((response) => response.json()) .then((json) => { - diagram.import(JSON.stringify(json)); + diagram?.import(JSON.stringify(json)); }) .catch(() => { throw new Error('Data Loading Error'); diff --git a/apps/demos/Demos/Diagram/Adaptability/ReactJs/App.js b/apps/demos/Demos/Diagram/Adaptability/ReactJs/App.js index 2b0a2fab366d..ff3790e7ab5e 100644 --- a/apps/demos/Demos/Diagram/Adaptability/ReactJs/App.js +++ b/apps/demos/Demos/Diagram/Adaptability/ReactJs/App.js @@ -3,13 +3,13 @@ import Diagram from 'devextreme-react/diagram'; import 'whatwg-fetch'; export default function App() { - const diagramRef = useRef(); + const diagramRef = useRef(null); useEffect(() => { - const diagram = diagramRef.current.instance(); + const diagram = diagramRef?.current?.instance(); fetch('../../../../data/diagram-flow.json') .then((response) => response.json()) .then((json) => { - diagram.import(JSON.stringify(json)); + diagram?.import(JSON.stringify(json)); }) .catch(() => { throw new Error('Data Loading Error'); diff --git a/apps/demos/Demos/Diagram/AdvancedDataBinding/React/App.tsx b/apps/demos/Demos/Diagram/AdvancedDataBinding/React/App.tsx index cf86a145251e..c000ee118b3e 100644 --- a/apps/demos/Demos/Diagram/AdvancedDataBinding/React/App.tsx +++ b/apps/demos/Demos/Diagram/AdvancedDataBinding/React/App.tsx @@ -14,7 +14,7 @@ const orgLinksDataSource = new ArrayStore({ data: service.getOrgLinks(), }); -function itemTypeExpr(obj: { type: string; }, value: string) { +function itemTypeExpr(obj: { type: string | undefined; }, value: string) { if (value) { obj.type = (value === 'rectangle') ? undefined : 'group'; return null; @@ -22,7 +22,7 @@ function itemTypeExpr(obj: { type: string; }, value: string) { return obj.type === 'group' ? 'ellipse' : 'rectangle'; } -function itemWidthExpr(obj: { width: number; type: string; }, value) { +function itemWidthExpr(obj: { width: number; type: string; }, value: number) { if (value) { obj.width = value; return null; @@ -30,7 +30,7 @@ function itemWidthExpr(obj: { width: number; type: string; }, value) { return obj.width || (obj.type === 'group' && 1.5) || 1; } -function itemHeightExpr(obj: { height: number; type: string; }, value) { +function itemHeightExpr(obj: { height: number; type: string; }, value: number) { if (value) { obj.height = value; return null; diff --git a/apps/demos/Demos/Diagram/Containers/React/App.tsx b/apps/demos/Demos/Diagram/Containers/React/App.tsx index 5581477e5ea7..562966006a34 100644 --- a/apps/demos/Demos/Diagram/Containers/React/App.tsx +++ b/apps/demos/Demos/Diagram/Containers/React/App.tsx @@ -4,14 +4,14 @@ import type { DiagramRef } from 'devextreme-react/diagram'; import 'whatwg-fetch'; export default function App() { - const diagramRef = useRef(); + const diagramRef = useRef(null); useEffect(() => { - const diagram = diagramRef.current.instance(); + const diagram = diagramRef?.current?.instance(); fetch('../../../../data/diagram-structure.json') .then((response) => response.json()) .then((json) => { - diagram.import(JSON.stringify(json)); + diagram?.import(JSON.stringify(json)); }) .catch(() => { throw new Error('Data Loading Error'); diff --git a/apps/demos/Demos/Diagram/Containers/ReactJs/App.js b/apps/demos/Demos/Diagram/Containers/ReactJs/App.js index e4b9902f2b68..7108739ad51d 100644 --- a/apps/demos/Demos/Diagram/Containers/ReactJs/App.js +++ b/apps/demos/Demos/Diagram/Containers/ReactJs/App.js @@ -3,13 +3,13 @@ import Diagram, { Group, Toolbox } from 'devextreme-react/diagram'; import 'whatwg-fetch'; export default function App() { - const diagramRef = useRef(); + const diagramRef = useRef(null); useEffect(() => { - const diagram = diagramRef.current.instance(); + const diagram = diagramRef?.current?.instance(); fetch('../../../../data/diagram-structure.json') .then((response) => response.json()) .then((json) => { - diagram.import(JSON.stringify(json)); + diagram?.import(JSON.stringify(json)); }) .catch(() => { throw new Error('Data Loading Error'); diff --git a/apps/demos/Demos/Diagram/CustomShapesWithTemplates/React/App.tsx b/apps/demos/Demos/Diagram/CustomShapesWithTemplates/React/App.tsx index d65b6c4bfcc1..49b059e111ce 100644 --- a/apps/demos/Demos/Diagram/CustomShapesWithTemplates/React/App.tsx +++ b/apps/demos/Demos/Diagram/CustomShapesWithTemplates/React/App.tsx @@ -24,7 +24,7 @@ export default function App() { const [currentEmployee, setCurrentEmployee] = useState>({}); const [popupVisible, setPopupVisible] = useState(false); - const showInfo = useCallback((employee) => { + const showInfo = useCallback((employee: EmployeeType) => { setCurrentEmployee(employee); setPopupVisible(true); }, [setCurrentEmployee, setPopupVisible]); diff --git a/apps/demos/Demos/Diagram/CustomShapesWithTemplates/React/CustomShapeTemplate.tsx b/apps/demos/Demos/Diagram/CustomShapesWithTemplates/React/CustomShapeTemplate.tsx index 0cbfdae22d2f..aadf7040e763 100644 --- a/apps/demos/Demos/Diagram/CustomShapesWithTemplates/React/CustomShapeTemplate.tsx +++ b/apps/demos/Demos/Diagram/CustomShapesWithTemplates/React/CustomShapeTemplate.tsx @@ -1,6 +1,7 @@ import React from 'react'; +import type { Employee } from './data.ts'; -export default function CustomShapeTemplate(employee, showInfo) { +export default function CustomShapeTemplate(employee: Employee, showInfo: () => void) { return ( {employee.Full_Name} diff --git a/apps/demos/Demos/Diagram/CustomShapesWithTemplatesWithEditing/React/App.tsx b/apps/demos/Demos/Diagram/CustomShapesWithTemplatesWithEditing/React/App.tsx index 705587d481c1..3b9ba4fad75d 100644 --- a/apps/demos/Demos/Diagram/CustomShapesWithTemplatesWithEditing/React/App.tsx +++ b/apps/demos/Demos/Diagram/CustomShapesWithTemplatesWithEditing/React/App.tsx @@ -19,6 +19,20 @@ import CustomShapeTemplate from './CustomShapeTemplate.tsx'; import CustomShapeToolboxTemplate from './CustomShapeToolboxTemplate.tsx'; import service from './data.ts'; import type { Employee } from './data.ts'; +import type { ValueChangedEvent } from 'devextreme/ui/text_box'; + +interface PopupContentFuncProps { + currentEmployee: Partial; + handleNameChange: (e: ValueChangedEvent) => void; + handleTitleChange: (e: ValueChangedEvent) => void; + handleCityChange: (e: ValueChangedEvent) => void; + handleStateChange: (e: ValueChangedEvent) => void; + handleEmailChange: (e: ValueChangedEvent) => void; + handleSkypeChange: (e: ValueChangedEvent) => void; + handlePhoneChange: (e: ValueChangedEvent) => void; + updateEmployeeClick: () => void; + cancelEditEmployeeClick: () => void; +} const pageCommands: DiagramTypes.Command[] = ['pageSize', 'pageOrientation', 'pageColor']; @@ -36,7 +50,7 @@ const employees = service.getEmployees(); const dataSource = new ArrayStore({ key: 'ID', data: employees, - onInserting(values, key) { + onInserting(values: Employee, key: string) { this.update(key, { ID: values.ID || (generatedID += 1), Full_Name: values.Full_Name || "Employee's Name", @@ -139,31 +153,31 @@ export default function App() { })); }, [setCurrentEmployee]); - const handleNameChange = useCallback((e: { value: any; }) => { + const handleNameChange = useCallback((e: ValueChangedEvent) => { handleChange('Full_Name', e.value); }, [handleChange]); - const handleTitleChange = useCallback((e: { value: any; }) => { + const handleTitleChange = useCallback((e: ValueChangedEvent) => { handleChange('Title', e.value); }, [handleChange]); - const handleCityChange = useCallback((e: { value: any; }) => { + const handleCityChange = useCallback((e: ValueChangedEvent) => { handleChange('City', e.value); }, [handleChange]); - const handleStateChange = useCallback((e: { value: any; }) => { + const handleStateChange = useCallback((e: ValueChangedEvent) => { handleChange('State', e.value); }, [handleChange]); - const handleEmailChange = useCallback((e: { value: any; }) => { + const handleEmailChange = useCallback((e: ValueChangedEvent) => { handleChange('Email', e.value); }, [handleChange]); - const handleSkypeChange = useCallback((e: { value: any; }) => { + const handleSkypeChange = useCallback((e: ValueChangedEvent) => { handleChange('Skype', e.value); }, [handleChange]); - const handlePhoneChange = useCallback((e: { value: any; }) => { + const handlePhoneChange = useCallback((e: ValueChangedEvent) => { handleChange('Mobile_Phone', e.value); }, [handleChange]); @@ -249,7 +263,7 @@ export default function App() { ); } -function PopupContentFunc(props) { +function PopupContentFunc(props: PopupContentFuncProps) { return ( <>
diff --git a/apps/demos/Demos/Diagram/CustomShapesWithTemplatesWithEditing/React/CustomShapeTemplate.tsx b/apps/demos/Demos/Diagram/CustomShapesWithTemplatesWithEditing/React/CustomShapeTemplate.tsx index 234137a5560f..ca83c6cdda75 100644 --- a/apps/demos/Demos/Diagram/CustomShapesWithTemplatesWithEditing/React/CustomShapeTemplate.tsx +++ b/apps/demos/Demos/Diagram/CustomShapesWithTemplatesWithEditing/React/CustomShapeTemplate.tsx @@ -1,7 +1,7 @@ import React from 'react'; import type { Employee } from './data'; -export default function CustomShapeTemplate(employee: Employee, editEmployee, deleteEmployee) { +export default function CustomShapeTemplate(employee: Employee, editEmployee: () => void, deleteEmployee: () => void) { const employeeName = employee ? employee.Full_Name : 'Employee\'s Name'; const employeeTitle = employee ? employee.Title : 'Employee\'s Title'; return ( diff --git a/apps/demos/Demos/Diagram/CustomShapesWithTexts/React/App.tsx b/apps/demos/Demos/Diagram/CustomShapesWithTexts/React/App.tsx index 5b42925e3e56..5ce3d8ea42cf 100644 --- a/apps/demos/Demos/Diagram/CustomShapesWithTexts/React/App.tsx +++ b/apps/demos/Demos/Diagram/CustomShapesWithTexts/React/App.tsx @@ -7,14 +7,14 @@ import 'whatwg-fetch'; const employees = service.getEmployees(); export default function App() { - const diagramRef = useRef(); + const diagramRef = useRef(null); useEffect(() => { - const diagram = diagramRef.current.instance(); + const diagram = diagramRef?.current?.instance(); fetch('../../../../data/diagram-employees.json') .then((response) => response.json()) .then((json) => { - diagram.import(JSON.stringify(json)); + diagram?.import(JSON.stringify(json)); }) .catch(() => { throw new Error('Data Loading Error'); diff --git a/apps/demos/Demos/Diagram/CustomShapesWithTexts/ReactJs/App.js b/apps/demos/Demos/Diagram/CustomShapesWithTexts/ReactJs/App.js index d0a9139f0d3f..0fb1e71411c7 100644 --- a/apps/demos/Demos/Diagram/CustomShapesWithTexts/ReactJs/App.js +++ b/apps/demos/Demos/Diagram/CustomShapesWithTexts/ReactJs/App.js @@ -5,13 +5,13 @@ import 'whatwg-fetch'; const employees = service.getEmployees(); export default function App() { - const diagramRef = useRef(); + const diagramRef = useRef(null); useEffect(() => { - const diagram = diagramRef.current.instance(); + const diagram = diagramRef?.current?.instance(); fetch('../../../../data/diagram-employees.json') .then((response) => response.json()) .then((json) => { - diagram.import(JSON.stringify(json)); + diagram?.import(JSON.stringify(json)); }) .catch(() => { throw new Error('Data Loading Error'); diff --git a/apps/demos/Demos/Diagram/ItemSelection/React/App.tsx b/apps/demos/Demos/Diagram/ItemSelection/React/App.tsx index d79be78ef3f7..cc6871316c83 100644 --- a/apps/demos/Demos/Diagram/ItemSelection/React/App.tsx +++ b/apps/demos/Demos/Diagram/ItemSelection/React/App.tsx @@ -1,9 +1,10 @@ import React, { useCallback, useState } from 'react'; import Diagram, { - Nodes, AutoLayout, Toolbox, PropertiesPanel, type DiagramTypes, + Nodes, AutoLayout, Toolbox, PropertiesPanel, } from 'devextreme-react/diagram'; import { ArrayStore } from 'devextreme-react/common/data'; import service from './data.ts'; +import type { DiagramTypes } from 'devextreme-react/diagram'; const dataSource = new ArrayStore({ key: 'ID', @@ -28,11 +29,11 @@ function onContentReady(e: DiagramTypes.ContentReadyEvent) { export default function App() { const [selectedItemNames, setSelectedItemNames] = useState('Nobody has been selected'); - const onSelectionChanged = useCallback(({ items }) => { + const onSelectionChanged = useCallback(({ items }: { items: DiagramTypes.Item[] }) => { let selectedItems = 'Nobody has been selected'; const filteredItems = items .filter((item) => item.itemType === 'shape') - .map((item) => item.text); + .map((item) => item.dataItem?.[textExpression]); if (filteredItems.length > 0) { selectedItems = filteredItems.join(', '); } diff --git a/apps/demos/Demos/Diagram/ItemSelection/ReactJs/App.js b/apps/demos/Demos/Diagram/ItemSelection/ReactJs/App.js index 0b18d0ca30a4..aca2265b85b7 100644 --- a/apps/demos/Demos/Diagram/ItemSelection/ReactJs/App.js +++ b/apps/demos/Demos/Diagram/ItemSelection/ReactJs/App.js @@ -29,7 +29,7 @@ export default function App() { let selectedItems = 'Nobody has been selected'; const filteredItems = items .filter((item) => item.itemType === 'shape') - .map((item) => item.text); + .map((item) => item.dataItem?.[textExpression]); if (filteredItems.length > 0) { selectedItems = filteredItems.join(', '); } diff --git a/apps/demos/Demos/Diagram/Overview/React/App.tsx b/apps/demos/Demos/Diagram/Overview/React/App.tsx index d8c5a25b47b0..74b91fbd6c8e 100644 --- a/apps/demos/Demos/Diagram/Overview/React/App.tsx +++ b/apps/demos/Demos/Diagram/Overview/React/App.tsx @@ -4,14 +4,14 @@ import type { DiagramRef } from 'devextreme-react/diagram'; import 'whatwg-fetch'; export default function App() { - const diagramRef = useRef(); + const diagramRef = useRef(null); useEffect(() => { - const diagram = diagramRef.current.instance(); + const diagram = diagramRef?.current?.instance(); fetch('../../../../data/diagram-flow.json') .then((response) => response.json()) .then((json) => { - diagram.import(JSON.stringify(json)); + diagram?.import(JSON.stringify(json)); }) .catch(() => { throw new Error('Data Loading Error'); diff --git a/apps/demos/Demos/Diagram/Overview/ReactJs/App.js b/apps/demos/Demos/Diagram/Overview/ReactJs/App.js index 987c94e484f9..70e3dcb80bb5 100644 --- a/apps/demos/Demos/Diagram/Overview/ReactJs/App.js +++ b/apps/demos/Demos/Diagram/Overview/ReactJs/App.js @@ -3,13 +3,13 @@ import Diagram from 'devextreme-react/diagram'; import 'whatwg-fetch'; export default function App() { - const diagramRef = useRef(); + const diagramRef = useRef(null); useEffect(() => { - const diagram = diagramRef.current.instance(); + const diagram = diagramRef?.current?.instance(); fetch('../../../../data/diagram-flow.json') .then((response) => response.json()) .then((json) => { - diagram.import(JSON.stringify(json)); + diagram?.import(JSON.stringify(json)); }) .catch(() => { throw new Error('Data Loading Error'); diff --git a/apps/demos/Demos/Diagram/ReadOnly/React/App.tsx b/apps/demos/Demos/Diagram/ReadOnly/React/App.tsx index 67529535f11a..c9cd1cf49fad 100644 --- a/apps/demos/Demos/Diagram/ReadOnly/React/App.tsx +++ b/apps/demos/Demos/Diagram/ReadOnly/React/App.tsx @@ -7,11 +7,11 @@ export default function App() { const diagramRef = useRef(null); useEffect(() => { - const diagram = diagramRef.current.instance(); + const diagram = diagramRef?.current?.instance(); fetch('../../../../data/diagram-structure.json') .then((response) => response.json()) .then((json) => { - diagram.import(JSON.stringify(json)); + diagram?.import(JSON.stringify(json)); }) .catch(() => { throw new Error('Data Loading Error'); diff --git a/apps/demos/Demos/Diagram/ReadOnly/ReactJs/App.js b/apps/demos/Demos/Diagram/ReadOnly/ReactJs/App.js index 71fb4f931953..a2de8d0f19b5 100644 --- a/apps/demos/Demos/Diagram/ReadOnly/ReactJs/App.js +++ b/apps/demos/Demos/Diagram/ReadOnly/ReactJs/App.js @@ -5,11 +5,11 @@ import 'whatwg-fetch'; export default function App() { const diagramRef = useRef(null); useEffect(() => { - const diagram = diagramRef.current.instance(); + const diagram = diagramRef?.current?.instance(); fetch('../../../../data/diagram-structure.json') .then((response) => response.json()) .then((json) => { - diagram.import(JSON.stringify(json)); + diagram?.import(JSON.stringify(json)); }) .catch(() => { throw new Error('Data Loading Error'); diff --git a/apps/demos/Demos/Diagram/UICustomization/React/App.tsx b/apps/demos/Demos/Diagram/UICustomization/React/App.tsx index 7c16c0d43263..35bdaae8eb49 100644 --- a/apps/demos/Demos/Diagram/UICustomization/React/App.tsx +++ b/apps/demos/Demos/Diagram/UICustomization/React/App.tsx @@ -11,10 +11,10 @@ import { Tab, Toolbox, ViewToolbar, - type DiagramTypes, } from 'devextreme-react/diagram'; import { confirm } from 'devextreme/ui/dialog'; import 'whatwg-fetch'; +import type { DiagramTypes, DiagramRef } from 'devextreme-react/diagram'; const pageCommands: DiagramTypes.Command[] = ['pageSize', 'pageOrientation', 'pageColor']; const menuCommands: DiagramTypes.Command[] = ['bringToFront', 'sendToBack', 'lock', 'unlock']; @@ -33,14 +33,14 @@ function onCustomCommand(e: DiagramTypes.CustomCommandEvent) { } export default function App() { - const diagramRef = useRef(null); + const diagramRef = useRef(null); useEffect(() => { - const diagram = diagramRef.current.instance(); + const diagram = diagramRef?.current?.instance(); fetch('../../../../data/diagram-flow.json') .then((response) => response.json()) .then((json) => { - diagram.import(JSON.stringify(json)); + diagram?.import(JSON.stringify(json)); }) .catch(() => { throw new Error('Data Loading Error'); diff --git a/apps/demos/Demos/Diagram/UICustomization/ReactJs/App.js b/apps/demos/Demos/Diagram/UICustomization/ReactJs/App.js index 1c850b1b3d8d..d72b4e8f2bca 100644 --- a/apps/demos/Demos/Diagram/UICustomization/ReactJs/App.js +++ b/apps/demos/Demos/Diagram/UICustomization/ReactJs/App.js @@ -33,11 +33,11 @@ function onCustomCommand(e) { export default function App() { const diagramRef = useRef(null); useEffect(() => { - const diagram = diagramRef.current.instance(); + const diagram = diagramRef?.current?.instance(); fetch('../../../../data/diagram-flow.json') .then((response) => response.json()) .then((json) => { - diagram.import(JSON.stringify(json)); + diagram?.import(JSON.stringify(json)); }) .catch(() => { throw new Error('Data Loading Error'); diff --git a/apps/demos/Demos/FileManager/BindingToEF/React/App.tsx b/apps/demos/Demos/FileManager/BindingToEF/React/App.tsx index 878ffa82922b..d0fecd28c27e 100644 --- a/apps/demos/Demos/FileManager/BindingToEF/React/App.tsx +++ b/apps/demos/Demos/FileManager/BindingToEF/React/App.tsx @@ -1,20 +1,22 @@ import React, { useCallback, useState } from 'react'; import FileManager, { - Permissions, ItemView, Details, Column, type FileManagerTypes, + Permissions, ItemView, Details, Column, } from 'devextreme-react/file-manager'; +import type { FileManagerTypes } from 'devextreme-react/file-manager'; import RemoteFileSystemProvider from 'devextreme/file_management/remote_provider'; const remoteProvider = new RemoteFileSystemProvider({ endpointUrl: 'https://js.devexpress.com/Demos/NetCore/api/file-manager-db', }); -const allowedFileExtensions = []; +const allowedFileExtensions: string[] = []; export default function App() { - const [currentPath, setCurrentPath] = useState('Documents/Reports'); + const [currentPath, setCurrentPath] = useState('Documents/Reports'); const onCurrentDirectoryChanged = useCallback((e: FileManagerTypes.CurrentDirectoryChangedEvent) => { - setCurrentPath(e.component.option('currentPath')); + const path = e?.component?.option('currentPath'); + path && setCurrentPath(path); }, []); return ( diff --git a/apps/demos/Demos/FileManager/BindingToEF/ReactJs/App.js b/apps/demos/Demos/FileManager/BindingToEF/ReactJs/App.js index bf2923ff06a0..3617094a12c8 100644 --- a/apps/demos/Demos/FileManager/BindingToEF/ReactJs/App.js +++ b/apps/demos/Demos/FileManager/BindingToEF/ReactJs/App.js @@ -11,7 +11,8 @@ const allowedFileExtensions = []; export default function App() { const [currentPath, setCurrentPath] = useState('Documents/Reports'); const onCurrentDirectoryChanged = useCallback((e) => { - setCurrentPath(e.component.option('currentPath')); + const path = e?.component?.option('currentPath'); + path && setCurrentPath(path); }, []); return ( string; +} + export default function App() { const [itemViewMode, setItemViewMode] = useState('thumbnails'); @@ -14,7 +19,7 @@ export default function App() { } }, [setItemViewMode]); - const customizeIcon = useCallback((fileSystemItem) => { + const customizeIcon = useCallback((fileSystemItem: CustomFileSystemItem) => { if (fileSystemItem.isDirectory) { return '../../../../images/thumbnails/folder.svg'; } diff --git a/apps/demos/Demos/FileManager/Overview/React/App.tsx b/apps/demos/Demos/FileManager/Overview/React/App.tsx index b4f1ab3ddff8..4e2edb65bb8f 100644 --- a/apps/demos/Demos/FileManager/Overview/React/App.tsx +++ b/apps/demos/Demos/FileManager/Overview/React/App.tsx @@ -1,5 +1,6 @@ import React, { useCallback, useState } from 'react'; -import FileManager, { type FileManagerTypes, Permissions } from 'devextreme-react/file-manager'; +import FileManager, { Permissions } from 'devextreme-react/file-manager'; +import type { FileManagerTypes } from 'devextreme-react/file-manager'; import RemoteFileSystemProvider from 'devextreme/file_management/remote_provider'; import { Popup } from 'devextreme-react/popup'; @@ -25,7 +26,8 @@ export default function App() { }, [setPopupVisible]); const onCurrentDirectoryChanged = useCallback((e: FileManagerTypes.CurrentDirectoryChangedEvent) => { - setCurrentPath(e.component.option('currentPath')); + const path = e?.component?.option('currentPath'); + path && setCurrentPath(path); }, [setCurrentPath]); return ( diff --git a/apps/demos/Demos/FileManager/Overview/ReactJs/App.js b/apps/demos/Demos/FileManager/Overview/ReactJs/App.js index 3457c350e565..767b44793426 100644 --- a/apps/demos/Demos/FileManager/Overview/ReactJs/App.js +++ b/apps/demos/Demos/FileManager/Overview/ReactJs/App.js @@ -25,7 +25,8 @@ export default function App() { }, [setPopupVisible]); const onCurrentDirectoryChanged = useCallback( (e) => { - setCurrentPath(e.component.option('currentPath')); + const path = e?.component?.option('currentPath'); + path && setCurrentPath(path); }, [setCurrentPath], ); diff --git a/apps/demos/Demos/FileManager/UICustomization/React/App.tsx b/apps/demos/Demos/FileManager/UICustomization/React/App.tsx index abc025dd1c01..1a2d675bef8d 100644 --- a/apps/demos/Demos/FileManager/UICustomization/React/App.tsx +++ b/apps/demos/Demos/FileManager/UICustomization/React/App.tsx @@ -5,12 +5,19 @@ import FileManager, { import type { FileManagerRef } from 'devextreme-react/file-manager'; import { fileItems, getItemInfo } from './data.ts'; +interface FileSystemItem { + name: string; + isDirectory: boolean; + size?: number; + items?: FileSystemItem[]; +} + export default function App() { const fileManagerRef = useRef(null); const createFile = useCallback(( fileExtension, - directory = fileManagerRef.current.instance().getCurrentDirectory(), + directory = fileManagerRef?.current?.instance()?.getCurrentDirectory(), ) => { const newItem = { __KEY__: Date.now(), @@ -19,12 +26,12 @@ export default function App() { size: 0, }; - if (!directory.isDirectory) { + if (!directory?.isDirectory) { return false; } - let array = null; - if (!directory.dataItem) { + let array: FileSystemItem[]; + if (!directory?.dataItem) { array = fileItems; } else { array = directory.dataItem.items; @@ -44,20 +51,20 @@ export default function App() { if (viewArea === 'navPane') { items = [directory]; } else { - items = fileManagerRef.current.instance().getSelectedItems(); + items = fileManagerRef?.current?.instance()?.getSelectedItems(); } - items.forEach((item: { dataItem: { category: any; }; }) => { + items?.forEach((item: { dataItem: { category: any; }; }) => { if (item.dataItem) { item.dataItem.category = newCategory; } }); - return items.length > 0; + return items && items.length > 0; }, []); const onItemClick = useCallback(({ itemData, viewArea, fileSystemItem }) => { - let updated = false; + let updated: boolean | undefined = false; const { extension, category } = getItemInfo(itemData.text); if (extension) { @@ -67,7 +74,7 @@ export default function App() { } if (updated) { - fileManagerRef.current.instance().refresh(); + fileManagerRef?.current?.instance()?.refresh(); } }, [createFile, updateCategory]); diff --git a/apps/demos/Demos/FileManager/UICustomization/React/data.ts b/apps/demos/Demos/FileManager/UICustomization/React/data.ts index fa360f887fba..8bfcd05f39d1 100644 --- a/apps/demos/Demos/FileManager/UICustomization/React/data.ts +++ b/apps/demos/Demos/FileManager/UICustomization/React/data.ts @@ -71,11 +71,13 @@ const fileExtensions = { 'Text Document': '.txt', 'RTF Document': '.rtf', Spreadsheet: '.xls', -}; +} as const; + +type FileExtensionName = keyof typeof fileExtensions; const categories = ['Work', 'Important', 'Home', 'None']; -export function getItemInfo(name: string) { +export function getItemInfo(name: FileExtensionName) { const extension = fileExtensions[name]; const category = extension ?? categories.find((cat) => cat === name); diff --git a/apps/demos/Demos/FileManager/UICustomization/ReactJs/App.js b/apps/demos/Demos/FileManager/UICustomization/ReactJs/App.js index 19e6446890ae..9b2af24e11a3 100644 --- a/apps/demos/Demos/FileManager/UICustomization/ReactJs/App.js +++ b/apps/demos/Demos/FileManager/UICustomization/ReactJs/App.js @@ -13,20 +13,20 @@ import { fileItems, getItemInfo } from './data.js'; export default function App() { const fileManagerRef = useRef(null); - const createFile = useCallback((fileExtension, directory = fileManagerRef.current - .instance() - .getCurrentDirectory()) => { + const createFile = useCallback((fileExtension, directory = fileManagerRef?.current + ?.instance() + ?.getCurrentDirectory()) => { const newItem = { __KEY__: Date.now(), name: `New file${fileExtension}`, isDirectory: false, size: 0, }; - if (!directory.isDirectory) { + if (!directory?.isDirectory) { return false; } - let array = null; - if (!directory.dataItem) { + let array; + if (!directory?.dataItem) { array = fileItems; } else { array = directory.dataItem.items; @@ -43,14 +43,14 @@ export default function App() { if (viewArea === 'navPane') { items = [directory]; } else { - items = fileManagerRef.current.instance().getSelectedItems(); + items = fileManagerRef?.current?.instance()?.getSelectedItems(); } - items.forEach((item) => { + items?.forEach((item) => { if (item.dataItem) { item.dataItem.category = newCategory; } }); - return items.length > 0; + return items && items.length > 0; }, []); const onItemClick = useCallback( ({ itemData, viewArea, fileSystemItem }) => { @@ -62,7 +62,7 @@ export default function App() { updated = updateCategory(category, fileSystemItem, viewArea); } if (updated) { - fileManagerRef.current.instance().refresh(); + fileManagerRef?.current?.instance()?.refresh(); } }, [createFile, updateCategory], diff --git a/apps/demos/Demos/Gantt/Appearance/React/TaskProgressTooltipContentTemplate.tsx b/apps/demos/Demos/Gantt/Appearance/React/TaskProgressTooltipContentTemplate.tsx index ceea676ebe4d..d250caf28468 100644 --- a/apps/demos/Demos/Gantt/Appearance/React/TaskProgressTooltipContentTemplate.tsx +++ b/apps/demos/Demos/Gantt/Appearance/React/TaskProgressTooltipContentTemplate.tsx @@ -1,6 +1,6 @@ import React from 'react'; -export default function TaskProgressTooltipContentTemplate({ progress }) { +export default function TaskProgressTooltipContentTemplate({ progress }: { progress: number }) { return (
{progress}%
diff --git a/apps/demos/Demos/Gantt/Appearance/React/TaskTooltipTemplate.tsx b/apps/demos/Demos/Gantt/Appearance/React/TaskTooltipTemplate.tsx index 4130f27c49b2..deae0590200c 100644 --- a/apps/demos/Demos/Gantt/Appearance/React/TaskTooltipTemplate.tsx +++ b/apps/demos/Demos/Gantt/Appearance/React/TaskTooltipTemplate.tsx @@ -1,10 +1,10 @@ import React from 'react'; -function getTimeEstimate({ start, end }) { +function getTimeEstimate({ start, end }: { start: number; end: number; }) { return Math.abs(start - end) / 36e5; } -function getTimeLeft({ start, end, progress }) { +function getTimeLeft({ start, end, progress }: { start: number; end: number; progress: number; }) { const timeEstimate = Math.abs(start - end) / 36e5; return Math.floor(((100 - progress) / 100) * timeEstimate); } diff --git a/apps/demos/Demos/Gantt/ContextMenu/React/App.tsx b/apps/demos/Demos/Gantt/ContextMenu/React/App.tsx index bd333cd8afe1..7c9e2de1e55e 100644 --- a/apps/demos/Demos/Gantt/ContextMenu/React/App.tsx +++ b/apps/demos/Demos/Gantt/ContextMenu/React/App.tsx @@ -8,6 +8,7 @@ import type { ICheckBoxOptions } from 'devextreme-react/check-box'; import { tasks, dependencies, resources, resourceAssignments, } from './data.ts'; +import type { ContextMenuPreparingEvent } from 'devextreme/ui/gantt'; function App() { const [ganttConfig, setGanttConfig] = useState({ @@ -76,7 +77,7 @@ function App() {
); - function onContextMenuPreparing(e: { cancel: any; }) { + function onContextMenuPreparing(e: ContextMenuPreparingEvent) { e.cancel = ganttConfig.disableContextMenu; } diff --git a/apps/demos/Demos/Gantt/ExportToPDF/React/App.tsx b/apps/demos/Demos/Gantt/ExportToPDF/React/App.tsx index 1ecd7cbf4826..057ead32419e 100644 --- a/apps/demos/Demos/Gantt/ExportToPDF/React/App.tsx +++ b/apps/demos/Demos/Gantt/ExportToPDF/React/App.tsx @@ -22,6 +22,17 @@ import { import { applyPlugin } from 'jspdf-autotable'; +import type { ValueChangedEvent as SelectBoxValueChangedEvent } from 'devextreme/ui/select_box'; +import type { ValueChangedEvent as NumberBoxValueChangedEvent } from 'devextreme/ui/number_box'; +import type { ValueChangedEvent as DateBoxValueChangedEvent } from 'devextreme/ui/date_box'; +import type { ValueChangedEvent as CheckBoxValueChangedEvent } from 'devextreme/ui/check_box'; + +type ValueChanged = + | SelectBoxValueChangedEvent + | NumberBoxValueChangedEvent + | DateBoxValueChangedEvent + | CheckBoxValueChangedEvent; + applyPlugin(jsPDF); type GanttPdfExportMode = 'all' | 'treeList' | 'chart'; @@ -32,7 +43,7 @@ const dateRanges = ['All', 'Visible', 'Custom']; const startTaskIndexLabel = { 'aria-label': 'Start Task Index' }; const endTaskIndexLabel = { 'aria-label': 'End Task Index' }; -class App extends React.Component { +class App extends React.Component { formatBoxRef: any; exportModeBoxRef: any; @@ -61,7 +72,7 @@ class App extends React.Component { endDateValueChanged: IDateBoxOptions['onValueChanged']; - constructor(props) { + constructor(props: object) { super(props); this.formatBoxRef = null; this.exportModeBoxRef = null; @@ -85,7 +96,7 @@ class App extends React.Component { onClick: this.exportButtonClick.bind(this), }; - const updateFn = (key) => (e) => this.setState({ [key]: e.value }); + const updateFn = (key: string) => (e: ValueChanged) => this.setState({ [key]: e.value }); this.formatBoxSelectionChanged = updateFn('formatBoxValue'); this.exportModeBoxSelectionChanged = updateFn('exportModeBoxValue'); @@ -249,7 +260,7 @@ class App extends React.Component { const isLandscape = this.state.landscapeCheckBoxValue; const exportMode: GanttPdfExportMode = this.state.exportModeBoxValue === 'Tree List' ? 'treeList' : this.state.exportModeBoxValue.toLowerCase() as GanttPdfExportMode; const dataRangeMode = this.state.dateRangeBoxValue.toLowerCase(); - let dataRange; + let dataRange: object; if (dataRangeMode === 'custom') { dataRange = { startIndex: this.state.startTaskIndex, @@ -258,7 +269,7 @@ class App extends React.Component { endDate: this.state.endDate, }; } else { - dataRange = dataRangeMode; + dataRange = { mode: dataRangeMode }; } pdfExporter.exportGantt( diff --git a/apps/demos/Demos/Gantt/ExportToPDF/ReactJs/App.js b/apps/demos/Demos/Gantt/ExportToPDF/ReactJs/App.js index 6cf6b5dbfb8a..ab474b10dbc5 100644 --- a/apps/demos/Demos/Gantt/ExportToPDF/ReactJs/App.js +++ b/apps/demos/Demos/Gantt/ExportToPDF/ReactJs/App.js @@ -245,7 +245,7 @@ class App extends React.Component { endDate: this.state.endDate, }; } else { - dataRange = dataRangeMode; + dataRange = { mode: dataRangeMode }; } pdfExporter .exportGantt({ diff --git a/apps/demos/Demos/Gantt/TaskTemplate/React/TaskTemplate.tsx b/apps/demos/Demos/Gantt/TaskTemplate/React/TaskTemplate.tsx index bba264f3ce31..83631e2f103c 100644 --- a/apps/demos/Demos/Gantt/TaskTemplate/React/TaskTemplate.tsx +++ b/apps/demos/Demos/Gantt/TaskTemplate/React/TaskTemplate.tsx @@ -1,5 +1,18 @@ import React from 'react'; +interface TaskTemplateProps { + taskData: { + id: number; + title: string; + progress: number; + }; + taskSize: { + width: number; + height: number; + }; + taskResources: { text: string }[]; +} + function getImagePath(taskId: number) { const imgPath = '../../../../images/employees'; let img = taskId < 10 ? `0${taskId}` : taskId; @@ -12,7 +25,7 @@ function getTaskColor(taskId: number) { return `custom-task-color-${color}`; } -export default function TaskTemplate({ taskData, taskSize, taskResources }) { +export default function TaskTemplate({ taskData, taskSize, taskResources }: TaskTemplateProps) { return (
diff --git a/apps/demos/tsconfig.react-check.json b/apps/demos/tsconfig.react-check.json index 331a208d2405..f4a7b2d526c6 100644 --- a/apps/demos/tsconfig.react-check.json +++ b/apps/demos/tsconfig.react-check.json @@ -17,14 +17,8 @@ "Demos/**/React/**/*.ts" ], "exclude": [ - "Demos/Diagram/**/React/**/*.ts", - "Demos/Diagram/**/React/**/*.tsx", - "Demos/FileManager/**/React/**/*.ts", - "Demos/FileManager/**/React/**/*.tsx", "Demos/FloatingActionButton/**/React/**/*.ts", "Demos/FloatingActionButton/**/React/**/*.tsx", - "Demos/Gantt/**/React/**/*.ts", - "Demos/Gantt/**/React/**/*.tsx", "Demos/VectorMap/**/React/**/*.ts", "Demos/VectorMap/**/React/**/*.tsx", "Demos/Localization/**/React/**/*.ts",