@topconsultnpm/sdkui-react-beta 6.8.0 → 6.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/base/TMLayout.d.ts +5 -4
- package/lib/components/base/TMLayout.js +1 -1
- package/lib/components/base/TMWaitPanel.d.ts +32 -0
- package/lib/components/base/TMWaitPanel.js +45 -0
- package/lib/components/forms/TMResultDialog.d.ts +20 -0
- package/lib/components/forms/TMResultDialog.js +39 -0
- package/lib/components/index.d.ts +2 -0
- package/lib/components/index.js +2 -5
- package/package.json +3 -3
|
@@ -39,13 +39,14 @@ declare const TMLayoutItem: ({ onClick, children, width, minWidth, maxWidth, max
|
|
|
39
39
|
height?: string;
|
|
40
40
|
minHeight?: string;
|
|
41
41
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
42
|
-
|
|
42
|
+
export interface ITMLayoutContainerProps {
|
|
43
|
+
children: React.ReactNode;
|
|
43
44
|
gap?: number;
|
|
44
45
|
justifyContent?: string;
|
|
45
46
|
alignItems?: string;
|
|
47
|
+
direction?: 'vertical' | 'horizontal';
|
|
46
48
|
onClick?: () => void;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
49
|
+
}
|
|
50
|
+
declare const TMLayoutContainer: ({ gap, onClick, justifyContent, alignItems, children, direction }: ITMLayoutContainerProps) => import("react/jsx-runtime").JSX.Element;
|
|
50
51
|
export { TMCard, TMLayoutItem, TMSplitterLayout };
|
|
51
52
|
export default TMLayoutContainer;
|
|
@@ -157,7 +157,7 @@ const TMSplitterLayout = ({ animation = false, showSeparator = true, separatorCo
|
|
|
157
157
|
sepDiv?.addEventListener('touchstart', onMouseDownSep);
|
|
158
158
|
return () => { sepDiv?.removeEventListener('mousedown', onMouseDownSep); sepDiv?.removeEventListener('touchstart', onMouseDownSep); };
|
|
159
159
|
}, [firstDivRef, secondDivRef, sepRef, isFrag, containerRef]);
|
|
160
|
-
return (_jsxs("div", { ref: containerRef, style: { display: 'flex', width: '100%', height: '100%', flexDirection: direction === 'vertical' ? 'column' : 'row', alignItems: 'flex-start', justifyContent: 'flex-start', position: 'relative' }, children: [_jsx("div", { style: { transition: animation ? 'ease 300ms' : 'none', overflow: 'hidden', height: direction === 'vertical' ? start[0] : '100%', minHeight: direction === 'vertical' ? min[0] : '100%', minWidth: direction === 'vertical' ? '100%' : min[0], width: direction === 'vertical' ? '100%' : start[0] }, ref: firstDivRef, children: React.Children.toArray(children)[0] }), !isFrag && _jsx("div", { ref: sepRef, style: { display: showSeparator ? 'block' : 'none', minWidth: direction === 'vertical' ? '100%' : `${separatorSize}px`, minHeight: direction === 'vertical' ? `${separatorSize}px` : '100%', backgroundColor: separatorColor, cursor: direction === 'vertical' ? 's-resize' : 'e-resize' } }), _jsx("div", { style: { transition: animation ? 'ease 300ms' : 'none', overflow: 'hidden', height: direction === 'vertical' ? start[1] : '100%', minHeight: direction === 'vertical' ? min[1] : '100%', minWidth: direction === 'vertical' ? '100%' : min[1], width: direction === 'vertical' ? '100%' : start[1] }, ref: secondDivRef, children: React.Children.toArray(children)[1] })] }));
|
|
160
|
+
return (_jsxs("div", { ref: containerRef, style: { display: 'flex', width: '100%', height: '100%', flexDirection: direction === 'vertical' ? 'column' : 'row', alignItems: 'flex-start', justifyContent: 'flex-start', position: 'relative' }, children: [_jsx("div", { style: { transition: animation ? 'ease 300ms' : 'none', overflow: 'hidden', height: direction === 'vertical' ? start[0] : '100%', minHeight: direction === 'vertical' ? min[0] : '100%', minWidth: direction === 'vertical' ? '100%' : min[0], width: direction === 'vertical' ? '100%' : start[0] }, ref: firstDivRef, children: React.Children.toArray(children)?.[0] }), !isFrag && _jsx("div", { ref: sepRef, style: { display: showSeparator ? 'block' : 'none', minWidth: direction === 'vertical' ? '100%' : `${separatorSize}px`, minHeight: direction === 'vertical' ? `${separatorSize}px` : '100%', backgroundColor: separatorColor, cursor: direction === 'vertical' ? 's-resize' : 'e-resize' } }), _jsx("div", { style: { transition: animation ? 'ease 300ms' : 'none', overflow: 'hidden', height: direction === 'vertical' ? start[1] : '100%', minHeight: direction === 'vertical' ? min[1] : '100%', minWidth: direction === 'vertical' ? '100%' : min[1], width: direction === 'vertical' ? '100%' : start[1] }, ref: secondDivRef, children: React.Children.toArray(children)?.[1] })] }));
|
|
161
161
|
};
|
|
162
162
|
const TMLayoutItem = ({ onClick, children, width = '100%', minWidth, maxWidth, maxHeight, height = '100%', minHeight }) => {
|
|
163
163
|
return (_jsx(StyledLayoutItem, { onClick: onClick, "$height": height, "$maxHeight": maxHeight, "$minHeight": minHeight, "$width": width, "$minWidth": minWidth, "$maxWidth": maxWidth, children: children }));
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ITMLayoutContainerProps } from './TMLayout';
|
|
2
|
+
interface ITMWaitPanelProps {
|
|
3
|
+
title?: string;
|
|
4
|
+
showPrimary?: boolean;
|
|
5
|
+
textPrimary?: string;
|
|
6
|
+
valuePrimary?: number;
|
|
7
|
+
maxValuePrimary?: number;
|
|
8
|
+
showSecondary?: boolean;
|
|
9
|
+
textSecondary?: string;
|
|
10
|
+
valueSecondary?: number;
|
|
11
|
+
maxValueSecondary?: number;
|
|
12
|
+
isCancelable?: boolean;
|
|
13
|
+
abortController?: AbortController;
|
|
14
|
+
onAbortClick?: (abortController: AbortController | undefined) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare const TMWaitPanel: (props: ITMWaitPanelProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
interface ITMLayoutWaitingContainerProps extends ITMLayoutContainerProps {
|
|
18
|
+
showWaitPanel?: boolean;
|
|
19
|
+
waitPanelTitle?: string;
|
|
20
|
+
showWaitPanelPrimary?: boolean;
|
|
21
|
+
waitPanelTextPrimary?: string;
|
|
22
|
+
waitPanelValuePrimary?: number;
|
|
23
|
+
waitPanelMaxValuePrimary?: number;
|
|
24
|
+
showWaitPanelSecondary?: boolean;
|
|
25
|
+
waitPanelTextSecondary?: string;
|
|
26
|
+
waitPanelValueSecondary?: number;
|
|
27
|
+
waitPanelMaxValueSecondary?: number;
|
|
28
|
+
isCancelable?: boolean;
|
|
29
|
+
abortController?: AbortController;
|
|
30
|
+
}
|
|
31
|
+
export declare const TMLayoutWaitingContainer: ({ showWaitPanel, showWaitPanelPrimary, showWaitPanelSecondary, waitPanelTitle, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, isCancelable, abortController, gap, onClick, justifyContent, alignItems, children, direction }: ITMLayoutWaitingContainerProps) => import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
import TMLayoutContainer from './TMLayout';
|
|
4
|
+
import { SDKUI_Localizator } from '../../helper';
|
|
5
|
+
const StyledWaitPanelOverlay = styled.div `
|
|
6
|
+
width: 100%;
|
|
7
|
+
height: 100%;
|
|
8
|
+
position: fixed;
|
|
9
|
+
top: 0;
|
|
10
|
+
left: 0;
|
|
11
|
+
z-index: 1501;
|
|
12
|
+
transition: all;
|
|
13
|
+
overflow: visible;
|
|
14
|
+
background-color: rgba(0, 0, 0, 0.4);
|
|
15
|
+
`;
|
|
16
|
+
const StyledWaitPanel = styled.div `
|
|
17
|
+
position: absolute;
|
|
18
|
+
top: 50%;
|
|
19
|
+
left: 50%;
|
|
20
|
+
transform: translate(-50%, -50%);
|
|
21
|
+
width: 300px;
|
|
22
|
+
height: ${(props) => props.$height};
|
|
23
|
+
background: white;
|
|
24
|
+
border-radius: 8px;
|
|
25
|
+
padding: 10px;
|
|
26
|
+
text-align: center;
|
|
27
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
|
28
|
+
`;
|
|
29
|
+
const StyledTitle = styled.h2 ` margin: 0; font-size: 1.5em; color: #333; `;
|
|
30
|
+
const StyledProgressBarContainer = styled.div ` width: 100%; height: 20px; background: #e0e0e0; border-radius: 10px; overflow: hidden; margin: 20px 0; `;
|
|
31
|
+
const StyledProgressBar = styled.div ` height: 100%; background: #4caf50; transition: width 0.3s ease; `;
|
|
32
|
+
const StyledProgressText = styled.p ` font-weight: bold; color: #333; margin: 0; `;
|
|
33
|
+
const StyledMessage = styled.p ` color: #666; font-size: 0.9em; margin-top: 10px; `;
|
|
34
|
+
const StyledAbortButton = styled.button ` background: #ff4d4d; color: white; border: none; border-radius: 5px; padding: 10px 20px; font-size: 1em; cursor: pointer; margin-top: 20px; &:hover { background: #ff6666; } `;
|
|
35
|
+
export const TMWaitPanel = (props) => {
|
|
36
|
+
let progressValue1 = 100 * (((props.valuePrimary ?? 0) / (props.maxValuePrimary ?? 0)) || 0);
|
|
37
|
+
let progressValue2 = 100 * (((props.valueSecondary ?? 0) / (props.maxValueSecondary ?? 0)) || 0);
|
|
38
|
+
return (_jsx(StyledWaitPanelOverlay, { children: _jsxs(StyledWaitPanel, { "$height": (props.showPrimary && props.showSecondary) ? '350px' : '250px', children: [_jsx(StyledTitle, { children: props.title }), props.showPrimary &&
|
|
39
|
+
_jsxs("div", { style: { width: '100%', height: '100px' }, children: [_jsx(StyledProgressBarContainer, { children: _jsx(StyledProgressBar, { style: { width: `${progressValue1.toFixed(2)}%` } }) }), _jsxs(StyledProgressText, { children: [progressValue1.toFixed(2), "%"] }), _jsx(StyledMessage, { children: props.textPrimary })] }), props.showSecondary &&
|
|
40
|
+
_jsxs("div", { style: { width: '100%', height: '100px' }, children: [_jsx(StyledProgressBarContainer, { children: _jsx(StyledProgressBar, { style: { width: `${progressValue2.toFixed(2)}%` } }) }), _jsxs(StyledProgressText, { children: [progressValue2.toFixed(2), "%"] }), _jsx(StyledMessage, { children: props.textSecondary })] }), props.isCancelable && _jsx(StyledAbortButton, { onClick: () => props.onAbortClick?.(props.abortController), children: SDKUI_Localizator.Abort })] }) }));
|
|
41
|
+
};
|
|
42
|
+
export const TMLayoutWaitingContainer = ({ showWaitPanel, showWaitPanelPrimary, showWaitPanelSecondary, waitPanelTitle, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, isCancelable, abortController, gap = 3, onClick, justifyContent = 'flex-start', alignItems = 'flex-start', children, direction = 'vertical' }) => {
|
|
43
|
+
return (_jsxs(TMLayoutContainer, { gap: gap, justifyContent: justifyContent, alignItems: alignItems, direction: direction, children: [children, showWaitPanel &&
|
|
44
|
+
_jsx(TMWaitPanel, { title: waitPanelTitle, showPrimary: showWaitPanelPrimary, textPrimary: waitPanelTextPrimary, valuePrimary: waitPanelValuePrimary, maxValuePrimary: waitPanelMaxValuePrimary, showSecondary: showWaitPanelSecondary, textSecondary: waitPanelTextSecondary, valueSecondary: waitPanelValueSecondary, maxValueSecondary: waitPanelMaxValueSecondary, isCancelable: isCancelable, abortController: abortController, onAbortClick: (abortController) => { setTimeout(() => { abortController?.abort(); }, 1000); } })] }));
|
|
45
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ResultTypes } from '@topconsultnpm/sdk-ts-beta';
|
|
3
|
+
export type ResultInfo = {
|
|
4
|
+
rowIndex: number;
|
|
5
|
+
id1: number;
|
|
6
|
+
id2: number;
|
|
7
|
+
resultType: ResultTypes;
|
|
8
|
+
description?: any;
|
|
9
|
+
};
|
|
10
|
+
interface ITMResultDialogProps {
|
|
11
|
+
result: ResultInfo[];
|
|
12
|
+
id1Caption: string | undefined;
|
|
13
|
+
id2Caption: string | undefined;
|
|
14
|
+
title: string;
|
|
15
|
+
}
|
|
16
|
+
declare const TMResultDialog: React.FC<ITMResultDialogProps>;
|
|
17
|
+
export default TMResultDialog;
|
|
18
|
+
export declare class TMResultManager {
|
|
19
|
+
static show(result: ResultInfo[], title: string, id1Caption: string | undefined, id2Caption: string | undefined): void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ResultTypes } from '@topconsultnpm/sdk-ts-beta';
|
|
3
|
+
import { DataGrid } from 'devextreme-react';
|
|
4
|
+
import { Column, HeaderFilter, Pager, Paging, Scrolling } from 'devextreme-react/cjs/data-grid';
|
|
5
|
+
import ReactDOM from 'react-dom/client';
|
|
6
|
+
import { IconSuccessCirlce, IconWarning, IconCloseCircle, IconInfo, SDKUI_Globals, SDKUI_Localizator } from '../../helper';
|
|
7
|
+
import { TMColors } from '../../utils/theme';
|
|
8
|
+
import ShowAlert from '../base/TMAlert';
|
|
9
|
+
import { TMDeviceProvider } from '../base/TMDeviceProvider';
|
|
10
|
+
import TMLayoutContainer from '../base/TMLayout';
|
|
11
|
+
import TMModal from '../base/TMModal';
|
|
12
|
+
const cellRender = (cellData) => {
|
|
13
|
+
const resultType = cellData.data.resultType;
|
|
14
|
+
switch (resultType) {
|
|
15
|
+
case ResultTypes.SUCCESS: return _jsx(IconSuccessCirlce, { fontSize: 22, color: TMColors.success });
|
|
16
|
+
case ResultTypes.WARNING: return _jsx(IconWarning, { fontSize: 22, color: TMColors.warning });
|
|
17
|
+
case ResultTypes.ERROR: return _jsx(IconCloseCircle, { fontSize: 22, color: TMColors.error });
|
|
18
|
+
case ResultTypes.INFO: return _jsx(IconInfo, { fontSize: 22, color: TMColors.info });
|
|
19
|
+
default: return _jsx("div", { children: cellData.text });
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const TMResultDialog = ({ title, result, id1Caption, id2Caption }) => {
|
|
23
|
+
return (_jsx(TMModal, { height: '60%', width: '60%', title: `Esito operazione - ${title}`, children: _jsxs(TMLayoutContainer, { children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'row', gap: '5px', padding: '3px', justifyContent: 'center', alignItems: 'center' }, children: [_jsx("p", { children: `Documenti elaborati: ${result.length}` }), _jsx(IconSuccessCirlce, { fontSize: 22, color: TMColors.success }), _jsx("p", { children: result.filter(o => o.resultType == ResultTypes.SUCCESS).length ?? 0 }), _jsx(IconWarning, { fontSize: 22, color: TMColors.warning }), _jsx("p", { children: result.filter(o => o.resultType == ResultTypes.WARNING).length ?? 0 }), _jsx(IconCloseCircle, { fontSize: 22, color: TMColors.error }), _jsx("p", { children: result.filter(o => o.resultType == ResultTypes.ERROR).length ?? 0 })] }), _jsxs(DataGrid, { dataSource: result, showColumnLines: SDKUI_Globals.dataGridShowColumnLines, showRowLines: SDKUI_Globals.dataGridShowRowLines, keyExpr: "rowIndex", width: "100%", height: "100%", columnResizingMode: "widget", allowColumnResizing: true, columnAutoWidth: true, children: [_jsx(Column, { dataField: 'resultType', caption: '', allowResizing: true, allowSorting: true, cellRender: cellRender }), _jsx(Column, { dataField: 'id1', caption: id1Caption }), _jsx(Column, { dataField: 'id2', caption: id2Caption }), _jsx(Column, { dataField: 'description', allowResizing: true, caption: SDKUI_Localizator.Description, allowSorting: true }), _jsx(Paging, { enabled: true, pageSize: 30 }), _jsx(Pager, { visible: true, showInfo: true, showNavigationButtons: true }), _jsx(Scrolling, { mode: 'standard', useNative: SDKUI_Globals.dataGridUseNativeScrollbar }), _jsx(HeaderFilter, { visible: true })] })] }) }));
|
|
24
|
+
};
|
|
25
|
+
export default TMResultDialog;
|
|
26
|
+
export class TMResultManager {
|
|
27
|
+
static show(result, title, id1Caption, id2Caption) {
|
|
28
|
+
const warningsCount = result.filter(o => o.resultType == ResultTypes.WARNING).length;
|
|
29
|
+
const errorsCount = result.filter(o => o.resultType == ResultTypes.ERROR).length;
|
|
30
|
+
if (warningsCount <= 0 && errorsCount <= 0) {
|
|
31
|
+
ShowAlert({ message: "Operazione completata con successo", mode: 'success', duration: 3000, title: title });
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
let container = document.createElement('div');
|
|
35
|
+
document.body.appendChild(container);
|
|
36
|
+
const root = ReactDOM.createRoot(container);
|
|
37
|
+
root.render(_jsx(TMDeviceProvider, { children: _jsx(TMResultDialog, { title: title, result: result, id1Caption: id1Caption, id2Caption: id2Caption }) }));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -9,6 +9,7 @@ export { default as TMModal } from './base/TMModal';
|
|
|
9
9
|
export * from './base/TMPopUp';
|
|
10
10
|
export * from './base/TMLayout';
|
|
11
11
|
export * from './base/Styled';
|
|
12
|
+
export * from './base/TMWaitPanel';
|
|
12
13
|
export { default as CounterBar } from './base/TMCounterBar';
|
|
13
14
|
export { default as TMProgressBar } from './base/TMProgressBar';
|
|
14
15
|
export { default as TMSpinner } from './base/TMSpinner';
|
|
@@ -43,6 +44,7 @@ export { default as TMLoginForm } from "./forms/TMLoginForm";
|
|
|
43
44
|
export { default as TMSaveForm } from "./forms/TMSaveForm";
|
|
44
45
|
export { default as TMApplyForm } from "./forms/TMApplyForm";
|
|
45
46
|
export { default as TMChooserForm } from "./forms/TMChooserForm";
|
|
47
|
+
export * from './forms/TMResultDialog';
|
|
46
48
|
export { default as TMPage } from "./pages/TMPage";
|
|
47
49
|
export { default as SettingsAppearance } from "./settings/SettingsAppearance";
|
|
48
50
|
export * from "./viewers/TMTidViewer";
|
package/lib/components/index.js
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
// base
|
|
2
|
-
// export { default as TMAbortBox } from './base/TMAbortBox'
|
|
3
2
|
export { default as ShowAlert } from './base/TMAlert';
|
|
4
3
|
export { default as TMButton } from './base/TMButton';
|
|
5
4
|
export { default as TMClosableList } from './base/TMClosableList';
|
|
6
5
|
export * from './base/TMContextMenu';
|
|
7
6
|
export { default as TMDropDownMenu } from './base/TMDropDownMenu';
|
|
8
7
|
export * from './base/TMListView';
|
|
9
|
-
// export { default as TMListView } from './base/TMListView'
|
|
10
8
|
export { default as TMList } from './base/TMList';
|
|
11
9
|
export { default as TMModal } from './base/TMModal';
|
|
12
10
|
export * from './base/TMPopUp';
|
|
13
11
|
export * from './base/TMLayout';
|
|
14
12
|
export * from './base/Styled';
|
|
13
|
+
export * from './base/TMWaitPanel';
|
|
15
14
|
export { default as CounterBar } from './base/TMCounterBar';
|
|
16
15
|
export { default as TMProgressBar } from './base/TMProgressBar';
|
|
17
16
|
export { default as TMSpinner } from './base/TMSpinner';
|
|
@@ -44,18 +43,16 @@ export * from './query/TMQueryResultForm';
|
|
|
44
43
|
//tab
|
|
45
44
|
export * from './base/TMTab';
|
|
46
45
|
// others
|
|
47
|
-
// export { default as TMAreaManager } from "./filesystem/TMAreaManager";
|
|
48
|
-
// export { default as TMFilePreviewer } from "./filesystem/TMFilePreviewer";
|
|
49
46
|
export { default as TMHeader } from "./sidebar/TMHeader";
|
|
50
47
|
export { default as TMSidebar } from "./sidebar/TMSidebar";
|
|
51
48
|
export { default as TMSidebarItem } from "./sidebar/TMSidebarItem";
|
|
52
|
-
// export { default as TMStatusbar } from "./sidebar/TMStatusBar";
|
|
53
49
|
export { default as TMSplitterLayout } from "./splitter/TMSplitterLayout";
|
|
54
50
|
//form
|
|
55
51
|
export { default as TMLoginForm } from "./forms/TMLoginForm";
|
|
56
52
|
export { default as TMSaveForm } from "./forms/TMSaveForm";
|
|
57
53
|
export { default as TMApplyForm } from "./forms/TMApplyForm";
|
|
58
54
|
export { default as TMChooserForm } from "./forms/TMChooserForm";
|
|
55
|
+
export * from './forms/TMResultDialog';
|
|
59
56
|
//page
|
|
60
57
|
export { default as TMPage } from "./pages/TMPage";
|
|
61
58
|
//settings
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topconsultnpm/sdkui-react-beta",
|
|
3
|
-
"version": "6.8.
|
|
3
|
+
"version": "6.8.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@topconsultnpm/sdk-ts-beta": "^6.8.0",
|
|
32
32
|
"buffer": "^6.0.3",
|
|
33
|
-
"devextreme": "24.
|
|
34
|
-
"devextreme-react": "24.
|
|
33
|
+
"devextreme": "24.2.3",
|
|
34
|
+
"devextreme-react": "24.2.3",
|
|
35
35
|
"react-router-dom": "^6.15.0",
|
|
36
36
|
"styled-components": "^6.1.1"
|
|
37
37
|
}
|