@topconsultnpm/sdkui-react-beta 6.7.25 → 6.7.26

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.
@@ -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
- // Render a title with a "Switch User" label and a close button styled as an icon
106
- const titleRender = () => (_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' }, children: [_jsx("h3", { children: SDKUI_Localizator.SwitchUser }), _jsx("button", { style: { background: 'none', border: 'none', fontSize: '16px', cursor: 'pointer' }, onClick: hidePopup, children: _jsx("i", { style: { fontSize: 20 }, className: "dx-icon-remove" }) })] }));
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("Error parsing the file content. Ensure the file is in the correct format."));
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);
@@ -3,15 +3,15 @@ import { FormModes, ITMSaveFormBaseProps } from '../../ts/types';
3
3
  declare const TMSaveForm: React.FC<ITMSaveFormBaseProps>;
4
4
  export default TMSaveForm;
5
5
  export declare const TMSaveFormStandardToolbar: ({ btnStyle, formMode, hasNavigation, isModified, errorsCount, onNext, onPrev, canNext, canPrev, onSaveAsync, onUndo }: {
6
- btnStyle: 'normal' | 'toolbar' | 'icon' | 'text';
6
+ btnStyle: "normal" | "toolbar" | "icon" | "text";
7
7
  formMode: FormModes;
8
8
  hasNavigation: boolean;
9
9
  isModified: boolean;
10
10
  errorsCount: number;
11
- onNext?: (() => void) | undefined;
12
- onPrev?: (() => void) | undefined;
13
- canNext?: boolean | undefined;
14
- canPrev?: boolean | undefined;
15
- onSaveAsync?: (() => Promise<void>) | undefined;
16
- onUndo?: (() => void) | undefined;
11
+ onNext?: () => void;
12
+ onPrev?: () => void;
13
+ canNext?: boolean;
14
+ canPrev?: boolean;
15
+ onSaveAsync?: () => Promise<void>;
16
+ onUndo?: () => void;
17
17
  }) => import("react/jsx-runtime").JSX.Element;