@topconsultnpm/sdkui-react-beta 6.11.111 → 6.11.113

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.
@@ -27,8 +27,10 @@ const TMDynDataListItemChooser = ({ tid, md, titleForm, openChooserBySingleClick
27
27
  }
28
28
  }
29
29
  setDynDl(d);
30
- if (!IsParametricQuery(d?.qd) && !dataSource)
30
+ if (!IsParametricQuery(d?.qd) && !dataSource) {
31
+ setDataSource(undefined);
31
32
  loadData().then((result) => { setDataSource(result); });
33
+ }
32
34
  }, [md]);
33
35
  useEffect(() => {
34
36
  if (!tid)
@@ -41,11 +43,6 @@ const TMDynDataListItemChooser = ({ tid, md, titleForm, openChooserBySingleClick
41
43
  }
42
44
  loadData().then((result) => {
43
45
  setDataSource(result);
44
- if (values && values.length > 0) {
45
- let description = result?.dtdResult?.rows?.filter(o => o[dynDl?.selectItemForValue ?? 0] == values?.[0])?.[0]?.[dynDl?.selectItemForDescription ?? 0];
46
- if (!description)
47
- onValueChanged?.(undefined);
48
- }
49
46
  });
50
47
  }, [queryParamsDynDataList, dynDl]);
51
48
  const loadData = async () => {
@@ -77,7 +74,7 @@ const TMDynDataListItemChooser = ({ tid, md, titleForm, openChooserBySingleClick
77
74
  _jsx(TMTooltip, { content: SDKUI_Localizator.ValueNotPresent, children: _jsx(IconWarning, { color: TMColors.warning }) });
78
75
  };
79
76
  const renderTemplate = () => {
80
- return (_jsxs(StyledDivHorizontal, { style: { minWidth: '125px' }, children: [_jsxs(StyledDivHorizontal, { children: [getIcon(), _jsx("p", { style: { marginLeft: '5px' }, children: getDescription() })] }), values && values.length > 1 && _jsx("p", { style: { marginLeft: '10px' }, children: `(+${values.length - 1} ${values.length == 2 ? 'altro' : 'altri'})` })] }));
77
+ return (_jsxs(StyledDivHorizontal, { style: { minWidth: '125px' }, children: [dataSource && _jsxs(StyledDivHorizontal, { children: [getIcon(), _jsx("p", { style: { marginLeft: '5px' }, children: getDescription() })] }), values && values.length > 1 && _jsx("p", { style: { marginLeft: '10px' }, children: `(+${values.length - 1} ${values.length == 2 ? 'altro' : 'altri'})` })] }));
81
78
  };
82
79
  return (_jsxs(_Fragment, { children: [_jsx(TMSummary, { placeHolder: placeHolder, icon: icon, labelColor: labelColor, backgroundColor: backgroundColor, buttons: buttons, showBorder: showBorder, readOnly: readOnly, hasValue: values && values.length > 0, showClearButton: showClearButton, iconEditButton: _jsx(IconSearch, { fontSize: 16 }), onEditorClick: () => !readOnly && setShowChooser(true), elementStyle: elementStyle, isModifiedWhen: isModifiedWhen, openEditorOnSummaryClick: openChooserBySingleClick, label: label, template: renderTemplate(), onClearClick: showClearButton ? () => { onValueChanged?.([]); } : undefined, validationItems: validationItems }), showChooser &&
83
80
  _jsx(TMDynDataListItemChooserForm, { TID: tid, MID: md?.id, dynDL: dynDl, title: titleForm, allowMultipleSelection: allowMultipleSelection, searchResult: dataSource, selectedIDs: values, onClose: () => setShowChooser(false), onChoose: (IDs) => {
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ interface IHtmlContentDisplay {
3
+ markup: string;
4
+ }
5
+ declare const TMHtmlContentDisplay: React.FC<IHtmlContentDisplay>;
6
+ export default TMHtmlContentDisplay;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import styled from 'styled-components';
3
+ const Wrapper = styled.div `
4
+ ul li {
5
+ list-style-position: inside;
6
+ }
7
+ ol li {
8
+ list-style-position: inside;
9
+ }
10
+ `;
11
+ const TMHtmlContentDisplay = ({ markup }) => {
12
+ return (_jsx(Wrapper, { children: _jsx("div", { dangerouslySetInnerHTML: { __html: markup } }) }));
13
+ };
14
+ export default TMHtmlContentDisplay;
@@ -0,0 +1,29 @@
1
+ import { ValidationItem } from '@topconsultnpm/sdk-ts-beta';
2
+ export interface ITMHtmlEditor {
3
+ /** Width of the editor (e.g., '100%', '500px') */
4
+ width?: string;
5
+ /** Height of the editor (e.g., '300px') */
6
+ height?: string;
7
+ /** Initial or current value of the editor content as an HTML string */
8
+ value?: string;
9
+ /** Callback function triggered when the content value changes */
10
+ onValueChanged?: (e: {
11
+ value: string;
12
+ }) => void;
13
+ /** If true, the editor is in read-only mode and content cannot be edited */
14
+ readOnly?: boolean;
15
+ /** Configuration for mention functionality (e.g., @mentions) */
16
+ mentionsConfig?: Array<{
17
+ dataSource: Array<{
18
+ text: string;
19
+ icon?: string;
20
+ }>;
21
+ searchExpr: string;
22
+ displayExpr: string;
23
+ valueExpr: string;
24
+ }>;
25
+ /** List of validation rules or checks to apply to the editor content */
26
+ validationItems?: Array<ValidationItem>;
27
+ }
28
+ declare const TMHtmlEditor: (props: ITMHtmlEditor) => import("react/jsx-runtime").JSX.Element;
29
+ export default TMHtmlEditor;
@@ -0,0 +1,66 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useRef, useState } from 'react';
3
+ import HtmlEditor, { Toolbar, Item } from 'devextreme-react/html-editor';
4
+ import TMVilViewer from '../base/TMVilViewer';
5
+ import TMTooltip from '../base/TMTooltip';
6
+ import TMButton from '../base/TMButton';
7
+ const TMHtmlEditor = (props) => {
8
+ const { width = "100%", height = "100%", readOnly = false, value = "", mentionsConfig, onValueChanged, validationItems } = props;
9
+ const editorRef = useRef(null); // Create a ref for the HtmlEditor
10
+ const [isEditorEnabled, setIsEditorEnabled] = useState(false);
11
+ const handlePaste = (e) => {
12
+ const clipboardData = e.clipboardData || window.clipboardData;
13
+ const pastedText = clipboardData.getData('text/plain'); // Get the plain text
14
+ e.preventDefault(); // Prevent default paste behavior
15
+ setMarkup(pastedText); // Set the pasted text as plain text
16
+ onValueChangeCallback(pastedText); // Call the value change callback
17
+ };
18
+ useEffect(() => {
19
+ const editor = editorRef.current?.instance()?.element();
20
+ if (editor) {
21
+ // Attach paste event listener to the editor's root DOM element
22
+ editor.addEventListener('paste', handlePaste);
23
+ }
24
+ // Cleanup the event listener when component unmounts
25
+ return () => {
26
+ if (editor) {
27
+ editor.removeEventListener('paste', handlePaste);
28
+ }
29
+ };
30
+ }, []);
31
+ const [markup, setMarkup] = useState(value);
32
+ useEffect(() => {
33
+ // Initialize markup with the value prop
34
+ setMarkup(value);
35
+ }, [value]);
36
+ useEffect(() => {
37
+ if (!isEditorEnabled) {
38
+ // When switching to plain text mode, strip HTML tags
39
+ const doc = new DOMParser().parseFromString(markup, 'text/html');
40
+ setMarkup(doc.body.textContent || "");
41
+ }
42
+ }, [isEditorEnabled]);
43
+ const onValueChangeCallback = (text) => {
44
+ setMarkup(text);
45
+ if (onValueChanged) {
46
+ onValueChanged({ value: text });
47
+ }
48
+ };
49
+ const hasValidationErrors = useMemo(() => {
50
+ return validationItems && validationItems.length > 0;
51
+ }, [validationItems]);
52
+ const toggleEditorMode = () => {
53
+ setIsEditorEnabled((prev) => !prev);
54
+ };
55
+ return (_jsxs("div", { children: [_jsx("div", { style: { position: 'absolute', top: '10px', right: '10px', zIndex: 10 }, children: _jsx(TMTooltip, { content: isEditorEnabled ? "Nascondi opzioni di formattazione" : "Mostra opzioni di formattazione", children: _jsx(TMButton, { btnStyle: "toolbar", onClick: toggleEditorMode, icon: isEditorEnabled ? _jsx("i", { className: 'dx-icon-eyeclose' }) : _jsx("i", { className: 'dx-icon-eyeopen' }) }) }) }), _jsx("div", { style: { borderWidth: '1px', borderStyle: 'solid', borderColor: hasValidationErrors ? "red" : "#e0e0e0 #e0e0e0 #616161", }, children: !isEditorEnabled ? (_jsx("textarea", { placeholder: "Digita un messaggio...", value: markup, onChange: (e) => onValueChangeCallback(e.target.value), maxLength: 1000, style: {
56
+ width,
57
+ height,
58
+ border: '1px solid #ddd',
59
+ boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
60
+ resize: 'none',
61
+ padding: '10px',
62
+ outline: 'none',
63
+ paddingRight: "40px"
64
+ } })) : (_jsx(HtmlEditor, { ref: editorRef, width: width, height: height, value: markup, onValueChange: onValueChangeCallback, readOnly: readOnly, mentions: mentionsConfig, style: { overflow: 'hidden', outline: "none" }, children: !readOnly && (_jsxs(Toolbar, { multiline: false, children: [_jsx(Item, { name: "undo" }), _jsx(Item, { name: "redo" }), _jsx(Item, { name: "separator" }), _jsx(Item, { name: "separator" }), _jsx(Item, { name: "bold" }), _jsx(Item, { name: "italic" }), _jsx(Item, { name: "underline" }), _jsx(Item, { name: "separator" }), _jsx(Item, { name: "alignLeft" }), _jsx(Item, { name: "alignCenter" }), _jsx(Item, { name: "alignRight" }), _jsx(Item, { name: "alignJustify" }), _jsx(Item, { name: "separator" }), _jsx(Item, { name: "orderedList" }), _jsx(Item, { name: "bulletList" }), _jsx(Item, { name: "separator" }), _jsx(Item, { name: "color" }), _jsx(Item, { name: "background" }), _jsx(Item, { name: "separator" }), _jsx(Item, { name: "link" })] })) })) }), _jsx(TMVilViewer, { vil: validationItems })] }));
65
+ };
66
+ export default TMHtmlEditor;
@@ -7,7 +7,7 @@ interface ITMMetadataEditorProps {
7
7
  value: string | undefined;
8
8
  queryParamsDynDataList?: string[];
9
9
  autoFocus?: boolean;
10
- containerElement: Element | undefined;
10
+ containerElement?: Element;
11
11
  disabled?: boolean;
12
12
  validationItems?: ValidationItem[];
13
13
  isLexProt?: number;
@@ -26,8 +26,4 @@ interface ITMMetadataEditorProps {
26
26
  }
27
27
  declare const TMMetadataEditor: React.FC<ITMMetadataEditorProps>;
28
28
  export default TMMetadataEditor;
29
- export declare const MetadataEditorContextMenu: React.MemoExoticComponent<({ target, menuItems }: {
30
- target: string;
31
- menuItems: any[];
32
- }) => import("react/jsx-runtime").JSX.Element>;
33
29
  export declare const useMetadataEditableList: () => [(mid: number | undefined) => boolean, (mid: number | undefined) => void];
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import React, { useEffect, useState } from 'react';
2
+ import { useEffect, useState } from 'react';
3
3
  import { MetadataDataDomains, MetadataDataTypes, DcmtTypeListCacheService, LayoutModes, AccessLevels, PlatformObjectValidator, QueryOperators, SDK_Globals, AppModules, MetadataFormats } from '@topconsultnpm/sdk-ts-beta';
4
4
  import { TMColors } from '../../utils/theme';
5
5
  import TMDataListItemChooser from '../choosers/TMDataListItemChooser';
@@ -10,7 +10,6 @@ import TMTextBox from './TMTextBox';
10
10
  import { TMMetadataIcon } from '../viewers/TMMidViewer';
11
11
  import TMTextArea from './TMTextArea';
12
12
  import { DateDisplayTypes } from '../../helper/Globalization';
13
- import ContextMenu from "devextreme-react/cjs/context-menu";
14
13
  const renderMetadataIcon = (tid, md, layoutMode, isMetadataSelected) => {
15
14
  return (_jsx(TMMetadataIcon, { isMetadataSelected: isMetadataSelected, layoutMode: layoutMode, md: md, tid: tid }));
16
15
  };
@@ -111,9 +110,6 @@ const TMMetadataEditor = ({ isSelected = false, customLabel, isReadOnly, isLexPr
111
110
  }
112
111
  };
113
112
  export default TMMetadataEditor;
114
- export const MetadataEditorContextMenu = React.memo(({ target, menuItems }) => {
115
- return (_jsx(ContextMenu, { dataSource: menuItems, target: `${target}` }));
116
- });
117
113
  export const useMetadataEditableList = () => {
118
114
  const [editableList, setEditableList] = useState([]);
119
115
  const addOrRemoveEditableList = (mid) => {
@@ -2,7 +2,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
2
2
  import { useEffect, useState } from "react";
3
3
  import styled from "styled-components";
4
4
  import { AccessLevels, DcmtTypeListCacheService, LayoutModes, MetadataDataDomains, MetadataDataTypes, MetadataValueDescriptor, SDK_Globals } from '@topconsultnpm/sdk-ts-beta';
5
- import { IconUndo, IconPencil, IconFunction, IconMenuVertical, IconDataList, SDKUI_Localizator, IconNull, stringIsNullOrEmpty } from "../../helper";
5
+ import { IconUndo, IconPencil, IconFunction, IconMenuVertical, IconDataList, SDKUI_Localizator, IconNull, stringIsNullOrEmpty, deepCompare } from "../../helper";
6
6
  import { TMColors } from "../../utils/theme";
7
7
  import TMButton from "../base/TMButton";
8
8
  import TMDropDownMenu from "../base/TMDropDownMenu";
@@ -27,10 +27,10 @@ export var AdvancedMenuButtons;
27
27
  })(AdvancedMenuButtons || (AdvancedMenuButtons = {}));
28
28
  const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerms = true, showAdvancedMenu = false, customMenuItems = [], showNullValueCheckBoxes, isOpenDistinctValues = false, openChooserBySingleClick, selectedMID, onFocusedItemChanged, layoutMode = LayoutModes.Update, metadataValues = [], metadataValuesOrig = [], TID, onValueChanged, onAdvancedMenuClick, validationItems }) => {
29
29
  const [dynDataListsToBeRefreshed, setDynDataListsToBeRefreshed] = useState([]);
30
- const [calcDynDataListsToBeRefreshed, setCalcDynDataListsToBeRefreshed] = useState();
31
30
  const [currentDTD, setCurrentDTD] = useState();
32
31
  const [isEditableList, addOrRemoveEditableList] = useMetadataEditableList();
33
32
  const [selectedItem, setSelectedItem] = useState(undefined);
33
+ const [prevMetadataValues, setPrevMetadataValues] = useState([]);
34
34
  const onChangeHandler = (newValue, mid) => {
35
35
  let newValues = structuredClone(metadataValues);
36
36
  const item = newValues.find(value => value.mid === mid);
@@ -48,8 +48,6 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
48
48
  dynDLToBeRefreshed = dynDataListsToBeRefreshed.find(o => o.midStarter === item?.mid);
49
49
  }
50
50
  }
51
- let md = currentDTD?.metadata?.find(o => o.id == mid);
52
- setCalcDynDataListsToBeRefreshed(md?.dataDomain === MetadataDataDomains.DynamicDataList);
53
51
  onValueChanged?.(newValues);
54
52
  };
55
53
  const editorValidationHandler = (mid) => {
@@ -73,29 +71,31 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
73
71
  useEffect(() => {
74
72
  DcmtTypeListCacheService.GetAsync(TID, true).then((resultDTD) => {
75
73
  setCurrentDTD(resultDTD);
76
- setCalcDynDataListsToBeRefreshed(true);
77
74
  });
78
75
  }, [TID]);
79
76
  useEffect(() => {
80
77
  if (metadataValues.length <= 0)
81
78
  return;
82
- if (calcDynDataListsToBeRefreshed && currentDTD?.id == TID) {
83
- loadDynDataListToBeRefreshedCascadeAsync(TID, metadataValues).then((result) => {
84
- setDynDataListsToBeRefreshed(result);
85
- setCalcDynDataListsToBeRefreshed(false);
86
- });
87
- }
88
- }, [JSON.stringify(metadataValues)]);
89
- const loadDynDataListToBeRefreshedCascadeAsync = async (tid, mds) => {
79
+ if (!currentDTD)
80
+ return;
81
+ //if no dynamic data list has changed we do not call APIs
82
+ if (deepCompare(metadataValues.filter(o => o.md?.dataDomain === MetadataDataDomains.DynamicDataList), prevMetadataValues.filter(o => o.md?.dataDomain === MetadataDataDomains.DynamicDataList)))
83
+ return;
84
+ setPrevMetadataValues(metadataValues);
85
+ loadDynDataListToBeRefreshedCascadeAsync(TID, metadataValues).then((result) => {
86
+ setDynDataListsToBeRefreshed(result);
87
+ });
88
+ }, [metadataValues, currentDTD]);
89
+ const loadDynDataListToBeRefreshedCascadeAsync = async (tid, mvdList) => {
90
90
  if (!tid)
91
91
  return [];
92
- if (mds.length <= 0)
92
+ if (mvdList.length <= 0)
93
93
  return [];
94
94
  let dynDLToBeRefreshed = [];
95
- for (const m of mds) {
95
+ for (const m of mvdList) {
96
96
  if (!m.value)
97
97
  continue;
98
- let data = await getDataDynDataListsToBeRefreshedAsync(tid, m.mid, [m.value ?? ""], dynDLToBeRefreshed.find(o => o.mid == m.mid)?.queryParams ?? []);
98
+ let data = await getDataDynDataListsToBeRefreshedAsync(tid, m.mid, m.value, dynDLToBeRefreshed.find(o => o.mid == m.mid)?.queryParams ?? []);
99
99
  if (!data)
100
100
  continue;
101
101
  for (const item of data)
@@ -103,11 +103,13 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
103
103
  }
104
104
  return dynDLToBeRefreshed;
105
105
  };
106
- const getDataDynDataListsToBeRefreshedAsync = async (tid, mid, values, qParams) => {
106
+ const getDataDynDataListsToBeRefreshedAsync = async (tid, mid, value, qParams) => {
107
107
  if (!tid)
108
108
  return;
109
109
  if (!mid)
110
110
  return;
111
+ if (stringIsNullOrEmpty(value))
112
+ return;
111
113
  let md = currentDTD?.metadata?.find(o => o.id == mid);
112
114
  if (md?.dataDomain !== MetadataDataDomains.DynamicDataList)
113
115
  return;
@@ -127,25 +129,23 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
127
129
  return;
128
130
  let toBeRefreshed = [];
129
131
  let dynDlDataSource = await SDK_Globals.tmSession?.NewSearchEngine().GetDynDataListValuesAsync(tid, mid, layoutMode, qParams);
130
- if (values && values.length > 0) {
131
- if (!d.onValueChanged_DynDataListsToBeRefreshed)
132
- return;
133
- let row = dynDlDataSource?.dtdResult?.rows?.filter(o => o[d.selectItemForValue ?? 0] == values?.[0]);
134
- if (!row || row.length <= 0)
135
- return;
136
- for (const t of d.onValueChanged_DynDataListsToBeRefreshed) {
137
- let mid = t.item1;
138
- let queryParams = [];
139
- if ((t.item2 ?? 0) >= 0)
140
- queryParams.push(row[0][t.item2 ?? 0]);
141
- if ((t.item3 ?? 0) >= 0)
142
- queryParams.push(row[0][t.item3 ?? 0]);
143
- if ((t.item4 ?? 0) >= 0)
144
- queryParams.push(row[0][t.item4 ?? 0]);
145
- if ((t.item5 ?? 0) >= 0)
146
- queryParams.push(row[0][t.item5 ?? 0]);
147
- toBeRefreshed.push({ mid: mid, queryParams: queryParams, midStarter: md?.id });
148
- }
132
+ if (!d.onValueChanged_DynDataListsToBeRefreshed)
133
+ return;
134
+ let row = dynDlDataSource?.dtdResult?.rows?.filter(o => o[d.selectItemForValue ?? 0] == value);
135
+ if (!row || row.length <= 0)
136
+ return;
137
+ for (const t of d.onValueChanged_DynDataListsToBeRefreshed) {
138
+ let mid = t.item1;
139
+ let queryParams = [];
140
+ if ((t.item2 ?? 0) >= 0)
141
+ queryParams.push(row[0][t.item2 ?? 0]);
142
+ if ((t.item3 ?? 0) >= 0)
143
+ queryParams.push(row[0][t.item3 ?? 0]);
144
+ if ((t.item4 ?? 0) >= 0)
145
+ queryParams.push(row[0][t.item4 ?? 0]);
146
+ if ((t.item5 ?? 0) >= 0)
147
+ queryParams.push(row[0][t.item5 ?? 0]);
148
+ toBeRefreshed.push({ mid: mid, queryParams: queryParams, midStarter: md?.id });
149
149
  }
150
150
  return toBeRefreshed;
151
151
  };
@@ -180,7 +180,7 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
180
180
  if (mvd)
181
181
  mvd.isSelected = newValue;
182
182
  onValueChanged?.(newValues);
183
- } }), _jsxs("div", { style: { position: 'relative', height: '100%', width: '100%', opacity: showNullValueCheckBoxes && item.isNull ? 0.4 : 1 }, children: [_jsx(TMMetadataEditor, { tid: TID, mid: item.mid, layoutMode: layoutMode, isLexProt: item.isLexProt, isSelected: isOpenDistinctValues && item.mid === selectedMID, isModifiedWhen: (item?.value ?? '') !== (metadataValuesOrig.find(m => m.mid === item.mid)?.value ?? ''), isReadOnly: showNullValueCheckBoxes ? item.isNull : undefined, isEditable: isEditable(item.mid) || item.isEditable, validationItems: editorValidationHandler(item.mid ?? 0), value: metadataValues.find(m => m.mid === item.mid)?.value, openChooserBySingleClick: openChooserBySingleClick, onValueChanged: (newValue) => onChangeHandler(newValue, item.mid ?? 0), onValueChange: (newValue) => onChangeHandler(newValue, item.mid ?? 0), containerElement: undefined, queryParamsDynDataList: dynDataListsToBeRefreshed.find(o => o.mid == item.mid)?.queryParams ?? [], onCascadeRefreshDynDataLists: (ddlToBeRefreshed) => {
183
+ } }), _jsxs("div", { style: { position: 'relative', height: '100%', width: '100%', opacity: showNullValueCheckBoxes && item.isNull ? 0.4 : 1 }, children: [_jsx(TMMetadataEditor, { tid: TID, mid: item.mid, layoutMode: layoutMode, isLexProt: item.isLexProt, isSelected: isOpenDistinctValues && item.mid === selectedMID, isModifiedWhen: (item.value ?? '') !== (metadataValuesOrig.find(m => m.mid === item.mid)?.value ?? ''), isReadOnly: showNullValueCheckBoxes ? item.isNull : undefined, isEditable: isEditable(item.mid) || item.isEditable, validationItems: editorValidationHandler(item.mid ?? 0), value: item.value, openChooserBySingleClick: openChooserBySingleClick, onValueChanged: (newValue) => { onChangeHandler(newValue, item.mid ?? 0); }, onValueChange: (newValue) => { onChangeHandler(newValue, item.mid ?? 0); }, queryParamsDynDataList: dynDataListsToBeRefreshed.find(o => o.mid == item.mid)?.queryParams ?? [], onCascadeRefreshDynDataLists: (ddlToBeRefreshed) => {
184
184
  let newDynDataListsToBeRefreshed = [];
185
185
  for (const item of dynDataListsToBeRefreshed) {
186
186
  let index = ddlToBeRefreshed.findIndex(o => o.mid == item.mid || (o.mid == -1 && o.midStarter == item.midStarter));
@@ -234,7 +234,7 @@ const StyledMetadataValuesContainer = styled.div `
234
234
  display: flex;
235
235
  flex-direction: column;
236
236
  width: 100%;
237
- height: calc(100%);
237
+ height: 100%;
238
238
  overflow: auto;
239
239
  padding: 0 10px 10px 10px;
240
240
  `;
@@ -46,7 +46,6 @@ export * from './base/TMTab';
46
46
  export { default as TMHeader } from "./sidebar/TMHeader";
47
47
  export { default as TMSidebar } from "./sidebar/TMSidebar";
48
48
  export { default as TMSidebarItem } from "./sidebar/TMSidebarItem";
49
- export { default as TMSplitterLayout } from "./splitter/TMSplitterLayout";
50
49
  export { default as TMLoginForm } from "./forms/Login/TMLoginForm";
51
50
  export { default as TMChangePassword } from "./forms/Login/ChangePassword";
52
51
  export { default as TMSaveForm } from "./forms/TMSaveForm";
@@ -53,7 +53,6 @@ export * from './base/TMTab';
53
53
  export { default as TMHeader } from "./sidebar/TMHeader";
54
54
  export { default as TMSidebar } from "./sidebar/TMSidebar";
55
55
  export { default as TMSidebarItem } from "./sidebar/TMSidebarItem";
56
- export { default as TMSplitterLayout } from "./splitter/TMSplitterLayout";
57
56
  //form
58
57
  export { default as TMLoginForm } from "./forms/Login/TMLoginForm";
59
58
  export { default as TMChangePassword } from "./forms/Login/ChangePassword";
@@ -107,6 +107,7 @@ export declare class SDKUI_Localizator {
107
107
  static get Error(): "Fehler" | "Error" | "Erreur" | "Erro" | "Errore";
108
108
  static get ErrorParsingFileContent(): "Fehler beim Parsen des Dateiinhalts. Stellen Sie sicher, dass die Datei im richtigen Format vorliegt." | "Error parsing the file content. Ensure the file is in the correct format." | "Error al analizar el contenido del archivo. Asegúrese de que el archivo esté en el formato correcto." | "Erreur lors de l'analyse du contenu du fichier. Assurez-vous que le fichier est dans le bon format." | "Erro ao analisar o conteúdo do arquivo. Certifique-se de que o arquivo está no formato correto." | "Errore durante l'analisi del contenuto del file. Assicurati che il file sia nel formato corretto.";
109
109
  static get EvaluateResult(): "Bewerten Sie das Ergebnis" | "Evaluate result" | "Valorar el resultado" | "Évalue les résultats" | "Avalia os resultados" | "Valuta il risultato";
110
+ static get ExpertMode(): "Expertenmodus" | "Expert mode" | "Modo experto" | "Mode expert" | "Modo especialista" | "Modalità esperto";
110
111
  static get Export(): "Exportieren" | "Export" | "Exportar" | "Exporter" | "Esporta";
111
112
  static get ExportMRN(): "Exportieren MRN" | "Export MRN" | "Exportar MRN" | "Exporter MRN";
112
113
  static get ExportMRNDayBack(): "Anzahl der Tage für die Exportdatenwiederherstellung (MRN)" | "Number of days for export data recovery (MRN)" | "Número de días para la recuperación de datos de exportación (MRN)" | "Nombre de jours pour la récupération des données d'exportation (MRN)" | "Número de dias para recuperação de dados de exportação (MRN)" | "Numero di giorni per il recupero dei dati di Export (MRN)";
@@ -315,6 +316,7 @@ export declare class SDKUI_Localizator {
315
316
  static get SortBy(): "Sortieren nach" | "Sort by" | "Ordenar por" | "Trier par" | "Ordinamento";
316
317
  static get Source(): "Ursprung" | "Source" | "Origen" | "Origem" | "Origine";
317
318
  static get SpecialOperators(): "Spezielle Operatoren" | "Special operators" | "Operadores especiales" | "Opérateurs spéciaux" | "Os operadores especiais" | "Operatori speciali";
319
+ static get StandardMode(): "Standardmodus" | "Standard mode" | "Modo estándar" | "Mode standard" | "Modo padrão" | "Modalità standard";
318
320
  static get Start(): "Zum Booten" | "Start" | "Arrancar" | "Pour démarrer" | "Para inicializar" | "Avviare";
319
321
  static get Statistics(): "Statistiken" | "Statistics" | "Estadística" | "Statistiques" | "Estatísticas" | "Statistiche";
320
322
  static get Summary(): "Zusammenfassung" | "Summary" | "Resumen" | "Résumé" | "Resumo" | "Riepilogo";
@@ -1031,6 +1031,16 @@ export class SDKUI_Localizator {
1031
1031
  default: return "Valuta il risultato";
1032
1032
  }
1033
1033
  }
1034
+ static get ExpertMode() {
1035
+ switch (this._cultureID) {
1036
+ case CultureIDs.De_DE: return "Expertenmodus";
1037
+ case CultureIDs.En_US: return "Expert mode";
1038
+ case CultureIDs.Es_ES: return "Modo experto";
1039
+ case CultureIDs.Fr_FR: return "Mode expert";
1040
+ case CultureIDs.Pt_PT: return "Modo especialista";
1041
+ default: return "Modalità esperto";
1042
+ }
1043
+ }
1034
1044
  static get Export() {
1035
1045
  switch (this._cultureID) {
1036
1046
  case CultureIDs.De_DE: return "Exportieren";
@@ -3108,6 +3118,16 @@ export class SDKUI_Localizator {
3108
3118
  default: return "Operatori speciali";
3109
3119
  }
3110
3120
  }
3121
+ static get StandardMode() {
3122
+ switch (this._cultureID) {
3123
+ case CultureIDs.De_DE: return "Standardmodus";
3124
+ case CultureIDs.En_US: return "Standard mode";
3125
+ case CultureIDs.Es_ES: return "Modo estándar";
3126
+ case CultureIDs.Fr_FR: return "Mode standard";
3127
+ case CultureIDs.Pt_PT: return "Modo padrão";
3128
+ default: return "Modalità standard";
3129
+ }
3130
+ }
3111
3131
  static get Start() {
3112
3132
  switch (this._cultureID) {
3113
3133
  case CultureIDs.De_DE: return "Zum Booten";
@@ -0,0 +1,4 @@
1
+ import { Meta } from '@storybook/react';
2
+ declare const _default: Meta;
3
+ export default _default;
4
+ export declare const HtmlEditor: any;
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { sortArgTypes } from './TMStoriesUtils';
3
+ import TMHtmlEditor from '../components/editors/TMHtmlEditor';
4
+ export default {
5
+ // The title will determine how the component appears in the sidebar of Storybook
6
+ title: 'Components/TMHtmlEditor',
7
+ // Specifies the component that is being documented in this story
8
+ component: TMHtmlEditor,
9
+ tags: ['autodocs'],
10
+ // Tags for categorizing the component within Storybook
11
+ argTypes: sortArgTypes({}),
12
+ };
13
+ /******* 1. Default Template and Default TMHtmlEditor *******/
14
+ const Template = (args) => _jsx(TMHtmlEditor, { ...args });
15
+ export const HtmlEditor = Template.bind({});
16
+ HtmlEditor.args = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.11.111",
3
+ "version": "6.11.113",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -1,17 +0,0 @@
1
- import React from 'react';
2
- interface ITMSplitterLayoutProps {
3
- vertical?: boolean;
4
- percentage?: boolean;
5
- primaryIndex?: number;
6
- primaryMinSize?: number;
7
- secondaryInitialSize?: number;
8
- secondaryMinSize?: number;
9
- height?: string;
10
- width?: string;
11
- onDragStart?: () => void;
12
- onDragEnd?: () => void;
13
- onSecondaryPaneSizeChange?: (size: number) => void;
14
- children?: React.ReactNode[];
15
- }
16
- declare const TMSplitterLayout: React.FC<ITMSplitterLayoutProps>;
17
- export default TMSplitterLayout;
@@ -1,215 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- // Questo componente è stato realizzato partendo da :
3
- // https://www.npmjs.com/package/react-splitter-layout
4
- import React, { useState, useEffect, useRef } from 'react';
5
- import styled from 'styled-components';
6
- import { TMColors } from '../../utils/theme';
7
- const clearSelection = () => {
8
- if (window.getSelection) {
9
- const selection = window.getSelection();
10
- if (selection) {
11
- selection.removeAllRanges();
12
- }
13
- // } else if (document.selection) {
14
- // document.selection.empty();
15
- }
16
- };
17
- const DEFAULT_SPLITTER_SIZE = 4;
18
- const StyledPane = styled.div.attrs(({ $isPrimary, $isVertical, $size, $unit }) => ({
19
- style: {
20
- flex: $isPrimary ? '1 1 auto' : '0 0 auto',
21
- height: $isVertical && !$isPrimary ? `${$size}${$unit}` : '',
22
- width: !$isVertical && !$isPrimary ? `${$size}${$unit}` : '',
23
- }
24
- })) `
25
- position: relative;
26
- overflow: auto;
27
- `;
28
- const StyledContainer = styled.div `
29
- position: absolute;
30
- display: flex;
31
- flex-direction: ${(props) => props.$isVertical ? 'column' : 'row'};
32
- width: ${(props) => props.$width ?? '100%'};
33
- height: ${(props) => props.$height ?? '100%'};
34
- overflow: hidden;
35
- ${(props) => props.$isResizing ? `cursor: ${props.$isVertical ? 'row-resize' : 'col-resize'}` : ''};
36
- `;
37
- const StyledSplitter = styled.div `
38
- ${(props) => props.$isVertical ? '' : 'flex: 0 0 auto;'};
39
- width: ${(props) => props.$isVertical ? '100%' : '2px'};
40
- height: ${(props) => props.$isVertical ? '2px' : '100%'};
41
- margin-left: ${(props) => props.$isVertical ? '0' : '2px'};
42
- margin-right: ${(props) => props.$isVertical ? '0' : '2px'};
43
- margin-top: ${(props) => props.$isVertical ? '2px' : '0'};
44
- margin-bottom: ${(props) => props.$isVertical ? '2px' : '0'};
45
- cursor: ${(props) => props.$isVertical ? 'row-resize' : 'col-resize'};
46
- background-color: ${(props) => props.$isResizing ? TMColors.primary : '#ccc'};
47
-
48
- &:hover {
49
- color: ${TMColors.primary};
50
- }
51
- `;
52
- const TMSplitterLayout = ({ vertical = false, percentage = false, primaryIndex = 0, primaryMinSize = 0, secondaryInitialSize, secondaryMinSize = 0, height = "100%", width = "100%", onDragStart, onDragEnd, onSecondaryPaneSizeChange, children = [], }) => {
53
- const [secondaryPaneSize, setSecondaryPaneSize] = useState(0);
54
- const [resizing, setResizing] = useState(false);
55
- const containerRef = useRef(null);
56
- const splitterRef = useRef(null);
57
- const getSecondaryPaneSize = (containerRect, splitterRect, clientPosition, offsetMouse) => {
58
- if (!containerRect || !splitterRect) {
59
- return 0; // Return a default value or handle the case as appropriate
60
- }
61
- let totalSize;
62
- let splitterSize;
63
- let offset;
64
- if (vertical) {
65
- totalSize = containerRect.height;
66
- splitterSize = splitterRect.height;
67
- offset = clientPosition.top - containerRect.top;
68
- }
69
- else {
70
- totalSize = containerRect.width;
71
- splitterSize = splitterRect.width;
72
- offset = clientPosition.left - containerRect.left;
73
- }
74
- if (offsetMouse) {
75
- offset -= splitterSize / 2;
76
- }
77
- if (offset < 0) {
78
- offset = 0;
79
- }
80
- else if (offset > totalSize - splitterSize) {
81
- offset = totalSize - splitterSize;
82
- }
83
- let secondaryPaneSize;
84
- if (primaryIndex === 1) {
85
- secondaryPaneSize = offset;
86
- }
87
- else {
88
- secondaryPaneSize = totalSize - splitterSize - offset;
89
- }
90
- let primaryPaneSize = totalSize - splitterSize - secondaryPaneSize;
91
- if (percentage) {
92
- secondaryPaneSize = (secondaryPaneSize * 100) / totalSize;
93
- primaryPaneSize = (primaryPaneSize * 100) / totalSize;
94
- splitterSize = (splitterSize * 100) / totalSize;
95
- totalSize = 100;
96
- }
97
- let l_primaryMinSize = primaryMinSize;
98
- let l_secondaryMinSize = secondaryMinSize;
99
- if (primaryPaneSize < l_primaryMinSize) {
100
- secondaryPaneSize = Math.max(secondaryPaneSize - (l_primaryMinSize - primaryPaneSize), 0);
101
- }
102
- else if (secondaryPaneSize < l_secondaryMinSize) {
103
- secondaryPaneSize = Math.min(totalSize - splitterSize - l_primaryMinSize, l_secondaryMinSize);
104
- }
105
- return secondaryPaneSize;
106
- };
107
- const handleResize = () => {
108
- if (splitterRef && !percentage) {
109
- const containerRect = containerRef.current?.getBoundingClientRect();
110
- const splitterRect = splitterRef.current?.getBoundingClientRect();
111
- const secondaryPaneSize = getSecondaryPaneSize(containerRect, splitterRect, {
112
- left: splitterRect?.left,
113
- top: splitterRect?.top
114
- }, false);
115
- setSecondaryPaneSize(secondaryPaneSize);
116
- }
117
- };
118
- const handleMouseMove = (e) => {
119
- if (resizing) {
120
- const containerRect = containerRef.current?.getBoundingClientRect();
121
- const splitterRect = splitterRef.current?.getBoundingClientRect();
122
- const secondaryPaneSize = getSecondaryPaneSize(containerRect, splitterRect, {
123
- left: e.clientX,
124
- top: e.clientY
125
- }, true);
126
- clearSelection();
127
- setSecondaryPaneSize(secondaryPaneSize);
128
- }
129
- };
130
- const handleTouchMove = (e) => {
131
- handleMouseMove(e.changedTouches[0]);
132
- };
133
- const handleSplitterMouseDown = () => {
134
- clearSelection();
135
- setResizing(true);
136
- };
137
- const handleMouseUp = () => {
138
- setResizing((prevResizing) => (prevResizing ? false : prevResizing));
139
- };
140
- useEffect(() => {
141
- const secondaryPaneSizeCalculation = () => {
142
- if (splitterRef.current && !percentage) {
143
- const containerRect = containerRef.current?.getBoundingClientRect();
144
- const splitterRect = splitterRef.current.getBoundingClientRect();
145
- const newSecondaryPaneSize = getSecondaryPaneSize(containerRect, splitterRect, { left: splitterRect.left, top: splitterRect.top }, false);
146
- setSecondaryPaneSize(newSecondaryPaneSize);
147
- }
148
- };
149
- window.addEventListener('resize', handleResize);
150
- let initialSecondaryPaneSize;
151
- if (typeof secondaryInitialSize !== 'undefined') {
152
- initialSecondaryPaneSize = secondaryInitialSize;
153
- }
154
- else {
155
- const containerRect = containerRef.current?.getBoundingClientRect();
156
- const splitterRect = splitterRef.current?.getBoundingClientRect() || { width: DEFAULT_SPLITTER_SIZE, height: DEFAULT_SPLITTER_SIZE };
157
- initialSecondaryPaneSize = getSecondaryPaneSize(containerRect, splitterRect, {
158
- left: containerRect.left + (containerRect.width - splitterRect.width) / 2,
159
- top: containerRect.top + (containerRect.height - splitterRect.height) / 2,
160
- }, false);
161
- }
162
- setSecondaryPaneSize(initialSecondaryPaneSize);
163
- // Call the calculation function initially
164
- secondaryPaneSizeCalculation();
165
- return () => {
166
- window.removeEventListener('resize', handleResize);
167
- };
168
- }, [secondaryInitialSize, percentage]);
169
- useEffect(() => {
170
- if (secondaryPaneSize !== 0 && onSecondaryPaneSizeChange) {
171
- onSecondaryPaneSizeChange(secondaryPaneSize);
172
- }
173
- if (resizing) {
174
- if (onDragStart) {
175
- onDragStart();
176
- }
177
- }
178
- else if (onDragEnd) {
179
- onDragEnd();
180
- }
181
- }, [secondaryPaneSize, resizing]);
182
- const childrenArray = React.Children.toArray(children).slice(0, 2);
183
- if (childrenArray.length === 0) {
184
- childrenArray.push(_jsx("div", {}));
185
- }
186
- else if (childrenArray.length === 1) {
187
- if (primaryIndex == 0)
188
- childrenArray.push(_jsx("div", {}));
189
- else
190
- childrenArray.unshift(_jsx("div", {}));
191
- }
192
- const thereAreChildrenEmpty = () => {
193
- return childrenArray.length == 2 && (elementIsEmpty(childrenArray[0]) || elementIsEmpty(childrenArray[1]));
194
- };
195
- const elementIsEmpty = (child) => {
196
- return Boolean(Object.keys(child.props).length === 0);
197
- };
198
- const wrappedChildren = childrenArray.map((child, i) => {
199
- let primary = true;
200
- let size = null;
201
- let unit = percentage ? '%' : 'px';
202
- if (childrenArray.length > 1 && i !== primaryIndex) {
203
- primary = false;
204
- size = secondaryPaneSize;
205
- }
206
- if (elementIsEmpty(child)) {
207
- size = 0;
208
- unit = "%";
209
- }
210
- return (_jsx(StyledPane, { "$isPrimary": primary, "$isVertical": vertical, "$size": size || 0, "$unit": percentage ? '%' : 'px', children: child }));
211
- });
212
- return (_jsxs(StyledContainer, { "$isResizing": resizing, "$isVertical": vertical, "$height": height, "$width": width, ref: containerRef, onMouseMove: handleMouseMove, onTouchMove: handleTouchMove, onMouseUp: handleMouseUp, onTouchEnd: handleMouseUp, children: [wrappedChildren[0], !thereAreChildrenEmpty() &&
213
- _jsx(StyledSplitter, { "$isResizing": resizing, "$isVertical": vertical, role: "separator", ref: splitterRef, onMouseDown: handleSplitterMouseDown, onTouchStart: handleSplitterMouseDown }), wrappedChildren.length > 1 && wrappedChildren[1]] }));
214
- };
215
- export default TMSplitterLayout;