@topconsultnpm/sdkui-react-beta 6.7.25 → 6.7.27
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/assets/icomoon.svg +96 -96
- package/lib/components/base/Styled.d.ts +22 -1919
- package/lib/components/base/TMAlert.d.ts +2 -3
- package/lib/components/base/TMButton.d.ts +11 -9
- package/lib/components/base/TMButton.js +11 -6
- package/lib/components/base/TMContextMenuOLD.d.ts +3 -274
- package/lib/components/base/TMDropDownMenu.d.ts +0 -1
- package/lib/components/base/TMEditorBase.d.ts +0 -1
- package/lib/components/base/TMLayout.d.ts +36 -36
- package/lib/components/base/TMTab.d.ts +4 -4
- package/lib/components/base/TMVilViewer.d.ts +1 -1
- package/lib/components/choosers/TMUserChooser.d.ts +5 -5
- package/lib/components/editors/TMEditorStyled.d.ts +20 -21
- package/lib/components/forms/TMLoginForm.d.ts +5 -5
- package/lib/components/forms/TMLoginPopupSaveLoginInfo.js +95 -4
- package/lib/components/forms/TMSaveForm.d.ts +25 -10
- package/lib/components/forms/TMSaveForm.js +23 -14
- package/lib/components/query/TMQueryEditor.d.ts +8 -550
- package/lib/components/query/TMQueryResult.d.ts +5 -5
- package/lib/components/query/TMQueryResultForm.d.ts +10 -10
- package/lib/components/sidebar/TMHeader.d.ts +2 -2
- package/lib/components/viewers/TMDataListItemViewer.d.ts +3 -3
- package/lib/components/viewers/TMMidViewer.d.ts +5 -5
- package/lib/components/viewers/TMTidViewer.d.ts +5 -5
- package/lib/helper/SDKUI_Localizator.d.ts +4 -0
- package/lib/helper/SDKUI_Localizator.js +64 -0
- package/lib/helper/helpers.d.ts +1 -1
- package/lib/hooks/useForm.d.ts +0 -1
- package/lib/hooks/useOutsideClick.d.ts +0 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
|
-
import { Accordion, LoadIndicator, Popup } from "devextreme-react";
|
|
3
|
+
import { Accordion, LoadIndicator, Popup, SelectBox } from "devextreme-react";
|
|
4
4
|
import { cultureIDsDataSource, LOGIN_HISTORY_KEY, } from "./TMLoginForm";
|
|
5
5
|
import { LocalStorageService, ResultTypes, SDK_Localizator, ValidationItem } from "@topconsultnpm/sdk-ts-beta";
|
|
6
6
|
import { Item } from "devextreme-react/cjs/accordion";
|
|
@@ -18,6 +18,7 @@ const TMLoginPopupSaveLoginInfo = (props) => {
|
|
|
18
18
|
const [searchText, setSearchText] = useState('');
|
|
19
19
|
// State to store selected items of type ITMLoginHistory
|
|
20
20
|
const [selectedItems, setSelectedItems] = useState([]);
|
|
21
|
+
const [selectedImportExportOption, setSelectedImportExportOption] = useState('');
|
|
21
22
|
// Retrieve the login history from local storage, sort by 'name', and return the sorted array (or an empty array if not found)
|
|
22
23
|
const getSortedLoginHistory = () => {
|
|
23
24
|
const loginHistory = LocalStorageService.getItem(LOGIN_HISTORY_KEY);
|
|
@@ -102,8 +103,98 @@ const TMLoginPopupSaveLoginInfo = (props) => {
|
|
|
102
103
|
setSearchText('');
|
|
103
104
|
hidePopup();
|
|
104
105
|
};
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Handles the click event for import/export functionality.
|
|
108
|
+
* - For 'import': Opens a file input dialog, reads the selected file,
|
|
109
|
+
* parses the content, and updates the application state.
|
|
110
|
+
* - For 'export': Exports the current login history to a timestamped file.
|
|
111
|
+
*/
|
|
112
|
+
const onImportExportItemClick = (e) => {
|
|
113
|
+
// Inner function to create a file input element: creates a file input element, configures it to accept a specific file type, and triggers a callback when a file is selected.
|
|
114
|
+
const createFileInput = (accept, onChange) => {
|
|
115
|
+
const input = document.createElement("input");
|
|
116
|
+
input.type = "file";
|
|
117
|
+
input.accept = accept;
|
|
118
|
+
input.addEventListener('change', (event) => {
|
|
119
|
+
const file = event.target.files?.[0];
|
|
120
|
+
if (file)
|
|
121
|
+
onChange(file);
|
|
122
|
+
});
|
|
123
|
+
input.click();
|
|
124
|
+
};
|
|
125
|
+
// Inner function to handle file reading and parsing: reads and parses a file's content as JSON, handling success and error cases.
|
|
126
|
+
const handleFileRead = (file, onSuccess, onError) => {
|
|
127
|
+
const reader = new FileReader();
|
|
128
|
+
reader.onload = () => {
|
|
129
|
+
try {
|
|
130
|
+
const fileContent = reader.result;
|
|
131
|
+
const parsedData = JSON.parse(fileContent);
|
|
132
|
+
onSuccess(parsedData);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
onError();
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
reader.readAsText(file);
|
|
139
|
+
};
|
|
140
|
+
// Inner function to generate modified data by appending new IDs and timestamp: generates a modified version of the parsed data by assigning new IDs, and appending timestamped names to each entry.
|
|
141
|
+
const generateModifiedData = (parsedData, existingHistory) => {
|
|
142
|
+
const maxId = Math.max(...existingHistory.map(item => Number(item.id) || 0), 0);
|
|
143
|
+
return parsedData.map((item, index) => {
|
|
144
|
+
const id = maxId + index + 1;
|
|
145
|
+
const currentDate = new Date();
|
|
146
|
+
const formattedDate = currentDate.toISOString().split('T')[0];
|
|
147
|
+
const time = currentDate.toTimeString().split(' ')[0];
|
|
148
|
+
return {
|
|
149
|
+
...item,
|
|
150
|
+
name: `${item.name}_${formattedDate}_${time}`,
|
|
151
|
+
id,
|
|
152
|
+
preferred: false
|
|
153
|
+
};
|
|
154
|
+
});
|
|
155
|
+
};
|
|
156
|
+
// Inner function to update the application state with new history data: updates the application's history state with the new data and stores it in local storage.
|
|
157
|
+
const updateHistoryState = (newData) => {
|
|
158
|
+
setHistoryState((prevState) => {
|
|
159
|
+
const updatedHistory = {
|
|
160
|
+
loginHistory: [...prevState.loginHistory, ...newData],
|
|
161
|
+
searchedLoginHistory: [...prevState.searchedLoginHistory, ...newData],
|
|
162
|
+
};
|
|
163
|
+
LocalStorageService.setItem(LOGIN_HISTORY_KEY, updatedHistory.loginHistory);
|
|
164
|
+
return { ...prevState, ...updatedHistory };
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
// Inner function to export data as a file with a generated filename: exports the provided data to a file, generating a filename with a timestamp
|
|
168
|
+
const exportToFile = (data, filenamePrefix) => {
|
|
169
|
+
const file = new Blob([JSON.stringify(data, null, 2)], { type: 'text/plain' });
|
|
170
|
+
const element = document.createElement("a");
|
|
171
|
+
const currentDate = new Date();
|
|
172
|
+
const dateString = currentDate.toISOString().split('T')[0]; // YYYY-MM-DD
|
|
173
|
+
const timeString = currentDate.toISOString().split('T')[1].split('.')[0].substring(0, 5); // HH:MM
|
|
174
|
+
element.href = URL.createObjectURL(file);
|
|
175
|
+
element.download = `${filenamePrefix}_${dateString}_${timeString}.txt`;
|
|
176
|
+
document.body.appendChild(element);
|
|
177
|
+
element.click();
|
|
178
|
+
document.body.removeChild(element);
|
|
179
|
+
};
|
|
180
|
+
// Main event handling logic for import/export
|
|
181
|
+
if (!e?.itemData)
|
|
182
|
+
return;
|
|
183
|
+
if (e.itemData.value === 'import') {
|
|
184
|
+
createFileInput(".txt", (file) => {
|
|
185
|
+
handleFileRead(file, (parsedData) => {
|
|
186
|
+
const modifiedData = generateModifiedData(parsedData, historyState.loginHistory);
|
|
187
|
+
updateHistoryState(modifiedData);
|
|
188
|
+
}, () => alert(SDKUI_Localizator.ErrorParsingFileContent));
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
else if (e.itemData.value === 'export') {
|
|
192
|
+
exportToFile(historyState.searchedLoginHistory, "TopMedia_SURFER_LOGIN_HISTORY");
|
|
193
|
+
}
|
|
194
|
+
setSelectedImportExportOption(e.itemData.value);
|
|
195
|
+
};
|
|
196
|
+
// titleRender function returns JSX to render a header with user interface components for import/export and closing the popup
|
|
197
|
+
const titleRender = () => (_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' }, children: [_jsx("h3", { children: SDKUI_Localizator.SwitchUser }), _jsxs("div", { style: { marginLeft: 'auto', display: 'flex', alignItems: 'center' }, children: [_jsx(SelectBox, { items: [{ text: SDKUI_Localizator.Import, value: 'import', disabled: false }, { text: SDKUI_Localizator.Export, value: 'export', disabled: historyState.loginHistory.length === 0 }], placeholder: SDKUI_Localizator.ImportExport, onItemClick: onImportExportItemClick, value: selectedImportExportOption, valueExpr: "value", displayExpr: "text" }), _jsx("button", { style: { background: 'none', border: 'none', fontSize: '16px', cursor: 'pointer', marginLeft: '10px' }, onClick: hidePopup, children: _jsx("i", { style: { fontSize: 20 }, className: "dx-icon-remove" }) })] })] }));
|
|
107
198
|
// Render a styled title with its ID and title content, using flex layout
|
|
108
199
|
const itemTitleRender = (titleObj, id) => {
|
|
109
200
|
const historyItem = historyState.loginHistory.find(item => item.name === titleObj.title);
|
|
@@ -117,7 +208,7 @@ const TMLoginPopupSaveLoginInfo = (props) => {
|
|
|
117
208
|
if (historyState.searchedLoginHistory.length === 0) {
|
|
118
209
|
return (_jsx("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", textAlign: "center", padding: "20px" }, children: SDKUI_Localizator.NoCredentialsSaved }));
|
|
119
210
|
}
|
|
120
|
-
return (_jsx("div", { style: { overflowY: "auto", maxHeight: "calc(100% - 60px)", padding: "10px" }, children: _jsx(Accordion, { selectedItems: selectedItems, onSelectionChanged: onSelectionChanged, collapsible: true, multiple: false, animationDuration: 300, noDataText: SDKUI_Localizator.NoCredentialsSaved, style: { border: "1px solid #ddd", borderRadius: "6px", boxShadow: "0 2px 6px rgba(0, 0, 0, 0.1)" }, children: historyState.searchedLoginHistory.map((data, index) => (_jsx(Item, { titleRender: (titleObj) => itemTitleRender(titleObj, index), title: data.name, children: _jsx(TMLoginItemTemplate, { data: data, reloadHistoryState: reloadHistoryState, fillLoginForm: fillLoginForm, deleteItemFromLocalStorage: deleteItemFromLocalStorage, setSelectedItems: setSelectedItems, setSearchText: setSearchText, historyState: historyState }) }, data.id))) }) }));
|
|
211
|
+
return (_jsx("div", { style: { overflowY: "auto", maxHeight: "calc(100% - 60px)", padding: "10px" }, children: _jsx(Accordion, { selectedItems: selectedItems, onSelectionChanged: onSelectionChanged, collapsible: true, multiple: false, animationDuration: 300, noDataText: SDKUI_Localizator.NoCredentialsSaved, style: { border: "1px solid #ddd", borderRadius: "6px", boxShadow: "0 2px 6px rgba(0, 0, 0, 0.1)" }, children: historyState.searchedLoginHistory.map((data, index) => (_jsx(Item, { titleRender: (titleObj) => itemTitleRender(titleObj, index + 1), title: data.name, children: _jsx(TMLoginItemTemplate, { data: data, reloadHistoryState: reloadHistoryState, fillLoginForm: fillLoginForm, deleteItemFromLocalStorage: deleteItemFromLocalStorage, setSelectedItems: setSelectedItems, setSearchText: setSearchText, historyState: historyState }) }, data.id))) }) }));
|
|
121
212
|
};
|
|
122
213
|
return (_jsxs(Popup, { maxWidth: 600, visible: visible, onHiding: closePopup, title: SDKUI_Localizator.SwitchUser, titleRender: titleRender, hideOnOutsideClick: false, showTitle: true, resizeEnabled: true, dragEnabled: true, showCloseButton: true, children: [_jsx("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", width: "100%", position: "sticky", top: 0, backgroundColor: "#fff", zIndex: 1, padding: "10px 0" }, children: _jsx(TMSearchBar, { maxWidth: "200px", marginLeft: "0px", onSearchValueChanged: (e) => setSearchText(e), searchValue: searchText }) }), renderPopupContent()] }));
|
|
123
214
|
};
|
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { FormModes, ITMSaveFormBaseProps } from '../../ts/types';
|
|
3
|
+
import { ButtonStyle } from '../base/TMButton';
|
|
3
4
|
declare const TMSaveForm: React.FC<ITMSaveFormBaseProps>;
|
|
4
5
|
export default TMSaveForm;
|
|
5
|
-
|
|
6
|
-
btnStyle:
|
|
6
|
+
interface ITMSaveFormButtonBase {
|
|
7
|
+
btnStyle: ButtonStyle;
|
|
8
|
+
iconColor?: string;
|
|
7
9
|
formMode: FormModes;
|
|
8
|
-
hasNavigation: boolean;
|
|
9
10
|
isModified: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface ITMSaveFormButtonPreviousProps extends ITMSaveFormButtonBase {
|
|
13
|
+
canPrev?: boolean;
|
|
14
|
+
onPrev?: () => void;
|
|
15
|
+
onSaveAsync?: () => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare const TMSaveFormButtonPrevious: ({ btnStyle, formMode, isModified, onPrev, canPrev, iconColor, onSaveAsync }: ITMSaveFormButtonPreviousProps) => import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
interface ITMSaveFormButtonNextProps extends ITMSaveFormButtonBase {
|
|
19
|
+
canNext?: boolean;
|
|
20
|
+
onNext?: () => void;
|
|
21
|
+
onSaveAsync?: () => Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export declare const TMSaveFormButtonNext: ({ btnStyle, formMode, isModified, onNext, canNext, iconColor, onSaveAsync }: ITMSaveFormButtonNextProps) => import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
interface ITMSaveFormButtonSaveProps extends ITMSaveFormButtonBase {
|
|
10
25
|
errorsCount: number;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
onSaveAsync?: () => Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
export declare const TMSaveFormButtonSave: ({ btnStyle, errorsCount, isModified, iconColor, onSaveAsync }: ITMSaveFormButtonSaveProps) => import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
interface ITMSaveFormButtonUndoProps extends ITMSaveFormButtonBase {
|
|
30
|
+
onUndo?: () => void;
|
|
31
|
+
}
|
|
32
|
+
export declare const TMSaveFormButtonUndo: ({ btnStyle, isModified, iconColor, onUndo }: ITMSaveFormButtonUndoProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -105,16 +105,10 @@ const TMSaveForm = ({ id, formMode = FormModes.Update, showToolbar = true, skipI
|
|
|
105
105
|
: renderSaveForm() }));
|
|
106
106
|
};
|
|
107
107
|
export default TMSaveForm;
|
|
108
|
-
export const
|
|
109
|
-
const
|
|
110
|
-
await onSaveAsync?.();
|
|
111
|
-
}
|
|
112
|
-
catch (ex) {
|
|
113
|
-
TMExceptionBoxManager.show({ exception: ex });
|
|
114
|
-
} };
|
|
115
|
-
const doNext = () => {
|
|
108
|
+
export const TMSaveFormButtonPrevious = ({ btnStyle, formMode, isModified, onPrev, canPrev, iconColor, onSaveAsync }) => {
|
|
109
|
+
const doPrev = () => {
|
|
116
110
|
if (!isModified) {
|
|
117
|
-
|
|
111
|
+
onPrev?.();
|
|
118
112
|
return;
|
|
119
113
|
}
|
|
120
114
|
TMMessageBoxManager.show({
|
|
@@ -125,7 +119,7 @@ export const TMSaveFormStandardToolbar = ({ btnStyle, formMode, hasNavigation, i
|
|
|
125
119
|
return;
|
|
126
120
|
if (e == ButtonNames.YES)
|
|
127
121
|
await onSaveAsync?.();
|
|
128
|
-
|
|
122
|
+
onPrev?.();
|
|
129
123
|
}
|
|
130
124
|
catch (ex) {
|
|
131
125
|
TMExceptionBoxManager.show({ exception: ex });
|
|
@@ -133,9 +127,12 @@ export const TMSaveFormStandardToolbar = ({ btnStyle, formMode, hasNavigation, i
|
|
|
133
127
|
}
|
|
134
128
|
});
|
|
135
129
|
};
|
|
136
|
-
|
|
130
|
+
return (_jsx(TMButton, { btnStyle: btnStyle, caption: SDKUI_Localizator.Previous, icon: _jsx(IconArrowUp, { color: iconColor }), disabled: !canPrev || isModified || formMode == FormModes.Create || formMode == FormModes.Duplicate, onClick: doPrev }));
|
|
131
|
+
};
|
|
132
|
+
export const TMSaveFormButtonNext = ({ btnStyle, formMode, isModified, onNext, canNext, iconColor, onSaveAsync }) => {
|
|
133
|
+
const doNext = () => {
|
|
137
134
|
if (!isModified) {
|
|
138
|
-
|
|
135
|
+
onNext?.();
|
|
139
136
|
return;
|
|
140
137
|
}
|
|
141
138
|
TMMessageBoxManager.show({
|
|
@@ -146,7 +143,7 @@ export const TMSaveFormStandardToolbar = ({ btnStyle, formMode, hasNavigation, i
|
|
|
146
143
|
return;
|
|
147
144
|
if (e == ButtonNames.YES)
|
|
148
145
|
await onSaveAsync?.();
|
|
149
|
-
|
|
146
|
+
onNext?.();
|
|
150
147
|
}
|
|
151
148
|
catch (ex) {
|
|
152
149
|
TMExceptionBoxManager.show({ exception: ex });
|
|
@@ -154,5 +151,17 @@ export const TMSaveFormStandardToolbar = ({ btnStyle, formMode, hasNavigation, i
|
|
|
154
151
|
}
|
|
155
152
|
});
|
|
156
153
|
};
|
|
157
|
-
return (
|
|
154
|
+
return (_jsx(TMButton, { btnStyle: btnStyle, caption: SDKUI_Localizator.Next, icon: _jsx(IconArrowDown, { color: iconColor }), disabled: !canNext || isModified || formMode == FormModes.Create || formMode == FormModes.Duplicate, onClick: doNext }));
|
|
155
|
+
};
|
|
156
|
+
export const TMSaveFormButtonSave = ({ btnStyle, errorsCount, isModified, iconColor, onSaveAsync }) => {
|
|
157
|
+
const doSaveAsync = async () => { try {
|
|
158
|
+
await onSaveAsync?.();
|
|
159
|
+
}
|
|
160
|
+
catch (ex) {
|
|
161
|
+
TMExceptionBoxManager.show({ exception: ex });
|
|
162
|
+
} };
|
|
163
|
+
return (_jsx(TMButton, { btnStyle: btnStyle, caption: SDKUI_Localizator.Save, icon: _jsx(IconSave, { color: iconColor }), keyGesture: "alt+s", backgroundColor: errorsCount > 0 ? TMColors.error : isModified ? TMColors.success : TMColors.disabled, onClick: doSaveAsync, color: "success", disabled: !(isModified && errorsCount <= 0) }));
|
|
164
|
+
};
|
|
165
|
+
export const TMSaveFormButtonUndo = ({ btnStyle, isModified, iconColor, onUndo }) => {
|
|
166
|
+
return (_jsx(TMButton, { btnStyle: btnStyle, caption: SDKUI_Localizator.Undo, icon: _jsx(IconUndo, { color: iconColor }), keyGesture: "alt+z", color: "tertiary", disabled: !isModified, onClick: onUndo }));
|
|
158
167
|
};
|