@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.
Files changed (30) hide show
  1. package/lib/assets/icomoon.svg +96 -96
  2. package/lib/components/base/Styled.d.ts +22 -1919
  3. package/lib/components/base/TMAlert.d.ts +2 -3
  4. package/lib/components/base/TMButton.d.ts +11 -9
  5. package/lib/components/base/TMButton.js +11 -6
  6. package/lib/components/base/TMContextMenuOLD.d.ts +3 -274
  7. package/lib/components/base/TMDropDownMenu.d.ts +0 -1
  8. package/lib/components/base/TMEditorBase.d.ts +0 -1
  9. package/lib/components/base/TMLayout.d.ts +36 -36
  10. package/lib/components/base/TMTab.d.ts +4 -4
  11. package/lib/components/base/TMVilViewer.d.ts +1 -1
  12. package/lib/components/choosers/TMUserChooser.d.ts +5 -5
  13. package/lib/components/editors/TMEditorStyled.d.ts +20 -21
  14. package/lib/components/forms/TMLoginForm.d.ts +5 -5
  15. package/lib/components/forms/TMLoginPopupSaveLoginInfo.js +95 -4
  16. package/lib/components/forms/TMSaveForm.d.ts +25 -10
  17. package/lib/components/forms/TMSaveForm.js +23 -14
  18. package/lib/components/query/TMQueryEditor.d.ts +8 -550
  19. package/lib/components/query/TMQueryResult.d.ts +5 -5
  20. package/lib/components/query/TMQueryResultForm.d.ts +10 -10
  21. package/lib/components/sidebar/TMHeader.d.ts +2 -2
  22. package/lib/components/viewers/TMDataListItemViewer.d.ts +3 -3
  23. package/lib/components/viewers/TMMidViewer.d.ts +5 -5
  24. package/lib/components/viewers/TMTidViewer.d.ts +5 -5
  25. package/lib/helper/SDKUI_Localizator.d.ts +4 -0
  26. package/lib/helper/SDKUI_Localizator.js +64 -0
  27. package/lib/helper/helpers.d.ts +1 -1
  28. package/lib/hooks/useForm.d.ts +0 -1
  29. package/lib/hooks/useOutsideClick.d.ts +0 -1
  30. 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
- // 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(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
- export declare const TMSaveFormStandardToolbar: ({ btnStyle, formMode, hasNavigation, isModified, errorsCount, onNext, onPrev, canNext, canPrev, onSaveAsync, onUndo }: {
6
- btnStyle: 'normal' | 'toolbar' | 'icon' | 'text';
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
- onNext?: (() => void) | undefined;
12
- onPrev?: (() => void) | undefined;
13
- canNext?: boolean | undefined;
14
- canPrev?: boolean | undefined;
15
- onSaveAsync?: (() => Promise<void>) | undefined;
16
- onUndo?: (() => void) | undefined;
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 TMSaveFormStandardToolbar = ({ btnStyle, formMode, hasNavigation, isModified, errorsCount, onNext, onPrev, canNext, canPrev, onSaveAsync, onUndo }) => {
109
- const doSaveAsync = async () => { try {
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
- onNext?.();
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
- onNext?.();
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
- const doPrev = () => {
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
- onPrev?.();
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
- onPrev?.();
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 (_jsxs(_Fragment, { children: [_jsx(TMButton, { btnStyle: btnStyle, caption: SDKUI_Localizator.Save, icon: _jsx(IconSave, { color: btnStyle === 'icon' ? 'white' : undefined }), keyGesture: "alt+s", backgroundColor: errorsCount > 0 ? TMColors.error : isModified ? TMColors.success : TMColors.disabled, onClick: doSaveAsync, color: "success", disabled: !(isModified && errorsCount <= 0) }), hasNavigation && _jsx(TMButton, { btnStyle: btnStyle, caption: SDKUI_Localizator.Previous, icon: _jsx(IconArrowUp, { color: btnStyle === 'icon' ? 'white' : undefined }), disabled: !canPrev || isModified || formMode == FormModes.Create || formMode == FormModes.Duplicate, onClick: doPrev }), hasNavigation && _jsx(TMButton, { btnStyle: btnStyle, caption: SDKUI_Localizator.Next, icon: _jsx(IconArrowDown, { color: btnStyle === 'icon' ? 'white' : undefined }), disabled: !canNext || isModified || formMode == FormModes.Create || formMode == FormModes.Duplicate, onClick: doNext }), _jsx(TMButton, { btnStyle: btnStyle, caption: SDKUI_Localizator.Undo, icon: _jsx(IconUndo, { color: btnStyle === 'icon' ? 'white' : undefined }), keyGesture: "alt+z", color: "tertiary", disabled: !isModified, onClick: onUndo })] }));
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
  };