@topconsultnpm/sdkui-react 6.19.0-test2 → 6.20.0-dev1.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.
Files changed (57) hide show
  1. package/lib/components/NewComponents/ContextMenu/TMContextMenu.d.ts +4 -0
  2. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +187 -0
  3. package/lib/components/NewComponents/ContextMenu/hooks.d.ts +11 -0
  4. package/lib/components/NewComponents/ContextMenu/hooks.js +48 -0
  5. package/lib/components/NewComponents/ContextMenu/index.d.ts +2 -0
  6. package/lib/components/NewComponents/ContextMenu/index.js +1 -0
  7. package/lib/components/NewComponents/ContextMenu/styles.d.ts +27 -0
  8. package/lib/components/NewComponents/ContextMenu/styles.js +308 -0
  9. package/lib/components/NewComponents/ContextMenu/types.d.ts +26 -0
  10. package/lib/components/NewComponents/ContextMenu/types.js +1 -0
  11. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.d.ts +4 -0
  12. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +370 -0
  13. package/lib/components/NewComponents/FloatingMenuBar/index.d.ts +2 -0
  14. package/lib/components/NewComponents/FloatingMenuBar/index.js +2 -0
  15. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +38 -0
  16. package/lib/components/NewComponents/FloatingMenuBar/styles.js +267 -0
  17. package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +30 -0
  18. package/lib/components/NewComponents/FloatingMenuBar/types.js +1 -0
  19. package/lib/components/NewComponents/Notification/Notification.d.ts +4 -0
  20. package/lib/components/NewComponents/Notification/Notification.js +60 -0
  21. package/lib/components/NewComponents/Notification/NotificationContainer.d.ts +8 -0
  22. package/lib/components/NewComponents/Notification/NotificationContainer.js +33 -0
  23. package/lib/components/NewComponents/Notification/index.d.ts +2 -0
  24. package/lib/components/NewComponents/Notification/index.js +2 -0
  25. package/lib/components/NewComponents/Notification/styles.d.ts +21 -0
  26. package/lib/components/NewComponents/Notification/styles.js +180 -0
  27. package/lib/components/NewComponents/Notification/types.d.ts +18 -0
  28. package/lib/components/NewComponents/Notification/types.js +1 -0
  29. package/lib/components/choosers/TMDynDataListItemChooser.js +5 -4
  30. package/lib/components/editors/TMMetadataValues.js +34 -12
  31. package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +74 -63
  32. package/lib/components/features/documents/TMDcmtForm.d.ts +1 -0
  33. package/lib/components/features/documents/TMDcmtForm.js +12 -5
  34. package/lib/components/features/documents/TMDcmtPreview.js +31 -37
  35. package/lib/components/features/search/TMSavedQuerySelector.js +1 -1
  36. package/lib/components/features/search/TMSearchQueryPanel.js +1 -1
  37. package/lib/components/features/search/TMSearchResult.js +106 -26
  38. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.d.ts +8 -0
  39. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.js +134 -0
  40. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +2 -2
  41. package/lib/components/features/search/TMSearchResultsMenuItems.js +40 -62
  42. package/lib/components/features/search/TMTreeSelector.js +1 -1
  43. package/lib/components/features/search/TMViewHistoryDcmt.d.ts +18 -0
  44. package/lib/components/features/search/TMViewHistoryDcmt.js +285 -0
  45. package/lib/components/grids/TMRecentsManager.js +1 -1
  46. package/lib/helper/SDKUI_Globals.d.ts +7 -0
  47. package/lib/helper/SDKUI_Globals.js +1 -0
  48. package/lib/helper/SDKUI_Localizator.d.ts +9 -0
  49. package/lib/helper/SDKUI_Localizator.js +121 -6
  50. package/lib/helper/TMIcons.d.ts +3 -1
  51. package/lib/helper/TMIcons.js +9 -1
  52. package/lib/helper/cicoHelper.d.ts +31 -0
  53. package/lib/helper/cicoHelper.js +155 -0
  54. package/lib/helper/helpers.d.ts +7 -0
  55. package/lib/helper/helpers.js +37 -5
  56. package/lib/helper/queryHelper.js +13 -1
  57. package/package.json +53 -53
@@ -0,0 +1,30 @@
1
+ import type { TMContextMenuItemProps } from '../ContextMenu';
2
+ export interface TMFloatingMenuItem {
3
+ id: string;
4
+ name: string;
5
+ icon: React.ReactNode;
6
+ onClick: () => void;
7
+ disabled?: boolean;
8
+ isPinned?: boolean;
9
+ originalMenuItem?: TMContextMenuItemProps;
10
+ }
11
+ export interface TMFloatingMenuBarProps {
12
+ containerRef: React.RefObject<HTMLElement | null>;
13
+ contextMenuItems?: TMContextMenuItemProps[];
14
+ storageKey?: string;
15
+ isConstrained?: boolean;
16
+ defaultPosition?: Position;
17
+ maxItems?: number;
18
+ }
19
+ export interface Position {
20
+ x: number;
21
+ y: number;
22
+ }
23
+ export interface TMFloatingMenuBarState {
24
+ position: Position;
25
+ isDragging: boolean;
26
+ isConfigMode: boolean;
27
+ orientation: 'horizontal' | 'vertical';
28
+ items: TMFloatingMenuItem[];
29
+ draggedItemIndex: number | null;
30
+ }
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { NotificationProps } from './types';
3
+ declare const Notification: React.FC<NotificationProps>;
4
+ export default Notification;
@@ -0,0 +1,60 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect, useRef } from 'react';
3
+ import * as S from './styles';
4
+ const Notification = ({ title, message, mode = 'info', position = 'top-right', duration = 3000, closable = false, stopOnMouseEnter = true, hasProgress = true, onClose, }) => {
5
+ const [state, setState] = useState({
6
+ visible: true,
7
+ isPaused: false,
8
+ progress: 100,
9
+ });
10
+ const timeoutRef = useRef(undefined);
11
+ const remainingTimeRef = useRef(duration);
12
+ const pauseTimeRef = useRef(0);
13
+ const closeNotification = () => {
14
+ setState(prev => ({ ...prev, visible: false }));
15
+ setTimeout(() => {
16
+ onClose?.();
17
+ }, 300);
18
+ };
19
+ useEffect(() => {
20
+ // Set up auto-close timer
21
+ timeoutRef.current = setTimeout(() => {
22
+ closeNotification();
23
+ }, duration);
24
+ return () => {
25
+ if (timeoutRef.current) {
26
+ clearTimeout(timeoutRef.current);
27
+ }
28
+ };
29
+ }, [duration]);
30
+ const handleMouseEnter = () => {
31
+ if (!stopOnMouseEnter)
32
+ return;
33
+ // Pause the timer
34
+ if (timeoutRef.current) {
35
+ clearTimeout(timeoutRef.current);
36
+ pauseTimeRef.current = Date.now();
37
+ }
38
+ setState(prev => ({ ...prev, isPaused: true }));
39
+ };
40
+ const handleMouseLeave = () => {
41
+ if (!stopOnMouseEnter)
42
+ return;
43
+ // Resume the timer with remaining time
44
+ const pauseDuration = Date.now() - pauseTimeRef.current;
45
+ remainingTimeRef.current = Math.max(0, remainingTimeRef.current - pauseDuration);
46
+ timeoutRef.current = setTimeout(() => {
47
+ closeNotification();
48
+ }, remainingTimeRef.current);
49
+ setState(prev => ({ ...prev, isPaused: false }));
50
+ };
51
+ const handleClose = (e) => {
52
+ e.stopPropagation();
53
+ if (timeoutRef.current) {
54
+ clearTimeout(timeoutRef.current);
55
+ }
56
+ closeNotification();
57
+ };
58
+ return (_jsxs(S.NotificationContainer, { "$position": position, "$mode": mode, "$visible": state.visible, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, role: "alert", "aria-live": "assertive", children: [_jsxs(S.NotificationContent, { children: [_jsx(S.NotificationTitle, { children: title }), _jsx(S.NotificationMessage, { children: message })] }), closable && (_jsx(S.CloseButton, { onClick: handleClose, "aria-label": "Close notification", children: "\u00D7" })), hasProgress && (_jsx(S.ProgressBar, { "$duration": duration, "$mode": mode, "$isPaused": state.isPaused }))] }));
59
+ };
60
+ export default Notification;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import type { NotificationPosition } from './types';
3
+ interface NotificationContainerProps {
4
+ position: NotificationPosition;
5
+ children: React.ReactNode;
6
+ }
7
+ declare const NotificationContainer: React.FC<NotificationContainerProps>;
8
+ export default NotificationContainer;
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import styled from 'styled-components';
3
+ const Container = styled.div `
4
+ position: fixed;
5
+ z-index: 10002;
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: 12px;
9
+ pointer-events: none;
10
+
11
+ ${props => {
12
+ const isTop = props.$position.startsWith('top');
13
+ const isBottom = props.$position.startsWith('bottom');
14
+ const isLeft = props.$position.endsWith('left');
15
+ const isRight = props.$position.endsWith('right');
16
+ const isCenter = props.$position.endsWith('center');
17
+ return `
18
+ ${isTop ? 'top: 24px;' : ''}
19
+ ${isBottom ? 'bottom: 24px;' : ''}
20
+ ${isLeft ? 'left: 24px;' : ''}
21
+ ${isRight ? 'right: 24px;' : ''}
22
+ ${isCenter ? 'left: 50%; transform: translateX(-50%);' : ''}
23
+ `;
24
+ }}
25
+
26
+ & > * {
27
+ pointer-events: auto;
28
+ }
29
+ `;
30
+ const NotificationContainer = ({ position, children }) => {
31
+ return _jsx(Container, { "$position": position, children: children });
32
+ };
33
+ export default NotificationContainer;
@@ -0,0 +1,2 @@
1
+ export { default } from './Notification';
2
+ export * from './types';
@@ -0,0 +1,2 @@
1
+ export { default } from './Notification';
2
+ export * from './types';
@@ -0,0 +1,21 @@
1
+ import type { NotificationMode, NotificationPosition } from './types';
2
+ export declare const NotificationContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
3
+ $position: NotificationPosition;
4
+ $mode: NotificationMode;
5
+ $visible: boolean;
6
+ }>> & string;
7
+ export declare const NotificationContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
8
+ export declare const NotificationTitle: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
9
+ export declare const NotificationMessage: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
10
+ export declare const CloseButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
11
+ export declare const ProgressBar: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("styled-components/dist/types").Substitute<import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
12
+ ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
13
+ }>, {
14
+ $duration: number;
15
+ $mode: NotificationMode;
16
+ $isPaused: boolean;
17
+ }>, {
18
+ $duration: number;
19
+ $mode: NotificationMode;
20
+ $isPaused: boolean;
21
+ }>> & string;
@@ -0,0 +1,180 @@
1
+ import styled, { keyframes } from 'styled-components';
2
+ const slideInFromTop = keyframes `
3
+ from {
4
+ opacity: 0;
5
+ transform: translateY(-100%);
6
+ }
7
+ to {
8
+ opacity: 1;
9
+ transform: translateY(0);
10
+ }
11
+ `;
12
+ const slideInFromBottom = keyframes `
13
+ from {
14
+ opacity: 0;
15
+ transform: translateY(100%);
16
+ }
17
+ to {
18
+ opacity: 1;
19
+ transform: translateY(0);
20
+ }
21
+ `;
22
+ const slideOut = keyframes `
23
+ from {
24
+ opacity: 1;
25
+ transform: scale(1);
26
+ }
27
+ to {
28
+ opacity: 0;
29
+ transform: scale(0.9);
30
+ }
31
+ `;
32
+ const getModeColors = (mode) => {
33
+ const colors = {
34
+ success: {
35
+ bg: '#10b981',
36
+ bgDark: '#059669',
37
+ border: '#34d399',
38
+ text: '#ffffff',
39
+ },
40
+ error: {
41
+ bg: '#ef4444',
42
+ bgDark: '#dc2626',
43
+ border: '#f87171',
44
+ text: '#ffffff',
45
+ },
46
+ warning: {
47
+ bg: '#f59e0b',
48
+ bgDark: '#d97706',
49
+ border: '#fbbf24',
50
+ text: '#ffffff',
51
+ },
52
+ info: {
53
+ bg: '#3b82f6',
54
+ bgDark: '#2563eb',
55
+ border: '#60a5fa',
56
+ text: '#ffffff',
57
+ },
58
+ };
59
+ return colors[mode];
60
+ };
61
+ export const NotificationContainer = styled.div `
62
+ position: relative;
63
+ z-index: 1;
64
+ min-width: 320px;
65
+ max-width: 420px;
66
+ background: ${props => getModeColors(props.$mode).bg};
67
+ border-radius: 12px;
68
+ box-shadow: 0 12px 40px rgba(0, 0, 0, 0.2),
69
+ 0 4px 12px rgba(0, 0, 0, 0.15);
70
+ padding: 16px 20px;
71
+ animation: ${props => {
72
+ if (!props.$visible)
73
+ return slideOut;
74
+ return props.$position.startsWith('top') ? slideInFromTop : slideInFromBottom;
75
+ }} 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;
76
+ backdrop-filter: blur(10px);
77
+ border: 2px solid ${props => getModeColors(props.$mode).border};
78
+ color: ${props => getModeColors(props.$mode).text};
79
+ overflow: hidden;
80
+
81
+ [data-theme='dark'] & {
82
+ background: ${props => getModeColors(props.$mode).bgDark};
83
+ box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4),
84
+ 0 4px 12px rgba(0, 0, 0, 0.3);
85
+ }
86
+
87
+ @media (max-width: 768px) {
88
+ min-width: 280px;
89
+ max-width: calc(100vw - 48px);
90
+ }
91
+ `;
92
+ export const NotificationContent = styled.div `
93
+ display: flex;
94
+ flex-direction: column;
95
+ gap: 6px;
96
+ padding-right: 24px;
97
+ `;
98
+ export const NotificationTitle = styled.div `
99
+ font-size: 16px;
100
+ font-weight: 600;
101
+ line-height: 1.4;
102
+ letter-spacing: -0.01em;
103
+ `;
104
+ export const NotificationMessage = styled.div `
105
+ font-size: 14px;
106
+ font-weight: 400;
107
+ line-height: 1.5;
108
+ opacity: 0.95;
109
+ `;
110
+ export const CloseButton = styled.button `
111
+ position: absolute;
112
+ top: 12px;
113
+ right: 12px;
114
+ background: transparent;
115
+ border: none;
116
+ color: inherit;
117
+ cursor: pointer;
118
+ width: 24px;
119
+ height: 24px;
120
+ display: flex;
121
+ align-items: center;
122
+ justify-content: center;
123
+ border-radius: 6px;
124
+ transition: all 0.15s ease;
125
+ font-size: 18px;
126
+ line-height: 1;
127
+ padding: 0;
128
+ opacity: 0.8;
129
+
130
+ &:hover {
131
+ opacity: 1;
132
+ background: rgba(255, 255, 255, 0.2);
133
+ transform: scale(1.1);
134
+ }
135
+
136
+ &:active {
137
+ transform: scale(0.95);
138
+ }
139
+
140
+ &:focus {
141
+ outline: 2px solid rgba(255, 255, 255, 0.5);
142
+ outline-offset: 2px;
143
+ }
144
+ `;
145
+ export const ProgressBar = styled.div.attrs(props => ({
146
+ style: {
147
+ animationDuration: `${props.$duration}ms`,
148
+ },
149
+ })) `
150
+ position: absolute;
151
+ bottom: 0;
152
+ left: 0;
153
+ height: 4px;
154
+ width: 100%;
155
+ background: ${props => getModeColors(props.$mode).border};
156
+ border-radius: 0 0 0 10px;
157
+ box-shadow: 0 0 8px ${props => getModeColors(props.$mode).border};
158
+ transform-origin: left;
159
+ animation: progress-shrink linear forwards;
160
+ animation-play-state: ${props => props.$isPaused ? 'paused' : 'running'};
161
+
162
+ @keyframes progress-shrink {
163
+ from {
164
+ transform: scaleX(1);
165
+ }
166
+ to {
167
+ transform: scaleX(0);
168
+ }
169
+ }
170
+
171
+ &::after {
172
+ content: '';
173
+ position: absolute;
174
+ top: 0;
175
+ right: 0;
176
+ width: 20px;
177
+ height: 100%;
178
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4));
179
+ }
180
+ `;
@@ -0,0 +1,18 @@
1
+ export type NotificationMode = 'warning' | 'info' | 'error' | 'success';
2
+ export type NotificationPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
3
+ export interface NotificationProps {
4
+ title: string;
5
+ message: string;
6
+ mode?: NotificationMode;
7
+ position?: NotificationPosition;
8
+ duration?: number;
9
+ closable?: boolean;
10
+ stopOnMouseEnter?: boolean;
11
+ hasProgress?: boolean;
12
+ onClose?: () => void;
13
+ }
14
+ export interface NotificationState {
15
+ visible: boolean;
16
+ isPaused: boolean;
17
+ progress: number;
18
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useEffect, useRef, useState } from 'react';
3
3
  import { DataColumnTypes, SDK_Localizator, DataListCacheService, SDK_Globals, LayoutModes } from '@topconsultnpm/sdk-ts';
4
- import { IconDetails, IconSearch, getDataColumnName, Globalization, SDKUI_Localizator, searchResultDescriptorToSimpleArray, IsParametricQuery, IconWarning } from '../../helper';
4
+ import { IconDetails, IconSearch, generateUniqueColumnKeys, Globalization, SDKUI_Localizator, searchResultDescriptorToSimpleArray, IsParametricQuery, IconWarning } from '../../helper';
5
5
  import { StyledDivHorizontal } from '../base/Styled';
6
6
  import TMSpinner from '../base/TMSpinner';
7
7
  import TMSummary from '../editors/TMSummary';
@@ -125,8 +125,9 @@ const TMDynDataListItemChooser = ({ tid, md, width = '100%', titleForm, openChoo
125
125
  export default TMDynDataListItemChooser;
126
126
  const cellRenderIcon = () => _jsx(IconDetails, {});
127
127
  export const TMDynDataListItemChooserForm = (props) => {
128
+ // Generate unique keys for all columns
129
+ const uniqueKeys = generateUniqueColumnKeys(props.searchResult?.dtdResult?.columns, props.searchResult?.fromTID);
128
130
  const dataColumns = props.searchResult?.dtdResult?.columns?.map((col, index) => {
129
- let keyField = getDataColumnName(props.searchResult?.fromTID, col);
130
131
  const isVisible = col.extendedProperties?.["Visibility"] != "Hidden";
131
132
  const dataType = () => {
132
133
  switch (col.dataType) {
@@ -136,9 +137,9 @@ export const TMDynDataListItemChooserForm = (props) => {
136
137
  default: return "string";
137
138
  }
138
139
  };
139
- return { dataField: keyField, caption: col.caption, visible: isVisible, dataType: dataType(), format: col.dataType === DataColumnTypes.DateTime ? Globalization.getDateDisplayFormat() : "" };
140
+ return { dataField: uniqueKeys[index], caption: col.caption, visible: isVisible, dataType: dataType(), format: col.dataType === DataColumnTypes.DateTime ? Globalization.getDateDisplayFormat() : "" };
140
141
  });
141
- const keyValue = props.searchResult ? getDataColumnName(props.searchResult?.fromTID, props.searchResult?.dtdResult?.columns?.[props.dynDL?.selectItemForValue ?? 0]) : '';
142
+ const keyValue = uniqueKeys[props.dynDL?.selectItemForValue ?? 0] ?? '';
142
143
  const getItems = async (refreshCache) => {
143
144
  if (!props.searchResult)
144
145
  return [];
@@ -10,7 +10,7 @@ import TMTooltip from "../base/TMTooltip";
10
10
  import TMCheckBox from "./TMCheckBox";
11
11
  import TMMetadataEditor, { useMetadataEditableList } from "./TMMetadataEditor";
12
12
  import { FormulaHelper } from "./TMFormulaEditor";
13
- import { DraftsMIDs, DSAttachsMIDs } from "../../ts";
13
+ import { ChronologyMIDs, DraftsMIDs, DSAttachsMIDs } from "../../ts";
14
14
  import { TMNothingToShow } from "../features/documents/TMDcmtPreview";
15
15
  import TMAccordion from "../base/TMAccordion";
16
16
  import TabPanel, { Item } from 'devextreme-react/tab-panel';
@@ -388,6 +388,20 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
388
388
  });
389
389
  return (_jsxs("div", { style: { width: '100%' }, children: [draftData.length > 0 && _jsx(TMAccordion, { title: SDKUI_Localizator.Draft, children: draftData.map(item => renderMetadataItem(item, isReadOnly)) }), checkOutData.length > 0 && _jsx(TMAccordion, { title: `${SDKUI_Localizator.CheckIn}/${SDKUI_Localizator.CheckOut}`, children: checkOutData.map(item => renderMetadataItem(item, true)) })] }));
390
390
  }, [metadataValues, showCheckBoxes, showNullValueCheckBoxes, isReadOnly, dynDataListsToBeRefreshed, validationItems, selectedMID, isOpenDistinctValues, openChooserBySingleClick, metadataValuesOrig]);
391
+ const layoutChronology = useMemo(() => {
392
+ const chronologyData = [];
393
+ metadataValues.forEach(item => {
394
+ switch (item.md?.id) {
395
+ case ChronologyMIDs.Ver:
396
+ case ChronologyMIDs.AuthorID:
397
+ chronologyData.push(item);
398
+ break;
399
+ default:
400
+ break;
401
+ }
402
+ });
403
+ return (_jsx("div", { style: { width: '100%' }, children: chronologyData.length > 0 && chronologyData.map(item => renderMetadataItem(item, isReadOnly)) }));
404
+ }, [metadataValues, showCheckBoxes, showNullValueCheckBoxes, isReadOnly, dynDataListsToBeRefreshed, validationItems, selectedMID, isOpenDistinctValues, openChooserBySingleClick, metadataValuesOrig]);
391
405
  const layoutDsAttachs = useMemo(() => {
392
406
  const dsAttachsData = [];
393
407
  metadataValues.forEach(item => {
@@ -443,10 +457,10 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
443
457
  if (layoutItem.type === LayoutItemTypes.LayoutRoot) {
444
458
  const children = getChildren(layoutItem.layoutItemID);
445
459
  if (layout.showTab) {
446
- return (_jsx(React.Fragment, { children: _jsx(TabPanel, { width: "100%", height: "100%", children: children.map(child => renderLayoutItem(child, depth, visited)) }) }, `root-${layoutItem.layoutItemID}`));
460
+ return (_jsx(React.Fragment, { children: _jsx(TabPanel, { width: "100%", height: "100%", children: children.map(child => (_jsx(React.Fragment, { children: renderLayoutItem(child, depth, visited) }, `child-${child.layoutItemID}`))) }) }, `root-${layoutItem.layoutItemID}`));
447
461
  }
448
462
  else {
449
- return (_jsx(React.Fragment, { children: children.map(child => renderLayoutItem(child, depth, visited)) }, `root-${layoutItem.layoutItemID}`));
463
+ return (_jsx(React.Fragment, { children: children.map(child => (_jsx(React.Fragment, { children: renderLayoutItem(child, depth, visited) }, `child-${child.layoutItemID}`))) }, `root-${layoutItem.layoutItemID}`));
450
464
  }
451
465
  }
452
466
  // Check if this is a LayoutGroup
@@ -458,25 +472,32 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
458
472
  const isCollapsed = false; // LayoutGroupDescriptor doesn't have collapsed property
459
473
  //Layout Grou da trasformare in tab
460
474
  if (groupDescriptor.orientation == LayoutGroupOrientations.Vertical && layout.showTab && layoutItem.parentID === 0) {
461
- return (_jsx(Item, { title: groupTitle, children: _jsx("div", { style: { width: '100%' }, children: children.map(child => renderLayoutItem(child, depth + 1, visited)) }) }, `group-tab-${layoutItem.layoutItemID}`));
475
+ return (_jsx(Item, { title: groupTitle, children: _jsx("div", { style: { width: '100%' }, children: children.map(child => (_jsx(React.Fragment, { children: renderLayoutItem(child, depth + 1, visited) }, `child-${child.layoutItemID}`))) }) }, `group-tab-${layoutItem.layoutItemID}`));
462
476
  }
463
477
  if (groupIsNoBorder && groupDescriptor.orientation !== LayoutGroupOrientations.Horizontal && children.length == 0) {
464
478
  return (_jsx("br", {}));
465
479
  }
480
+ if (!groupIsNoBorder && groupDescriptor.orientation === LayoutGroupOrientations.Horizontal && children.length > 0 && groupTitle.length > 0) {
481
+ return (
482
+ // <div key={`group-horizontal-${layoutItem.layoutItemID}`} style={{ display: 'flex', flexDirection: 'row', flexWrap: 'wrap', gap: '3px' }}>
483
+ _jsxs("div", { style: { position: 'relative', border: '2px solid #CAD9EB', borderRadius: '3px', padding: '12px 6px 6px', margin: '10px', display: 'flex', flexDirection: 'row', flexWrap: 'wrap', gap: '3px' }, children: [_jsx("div", { style: { position: 'absolute', top: '-10px', left: '10px', padding: '0 8px', backgroundColor: '#fff', fontWeight: 600, fontSize: '1rem', color: TMColors.primaryColor, }, children: groupTitle }), children.map(child => (_jsx(React.Fragment, { children: renderLayoutItem(child, depth + 1, visited) }, `child-${child.layoutItemID}`))), " "] }, `group-horizontal-${layoutItem.layoutItemID}`)
484
+ // </div>
485
+ );
486
+ }
466
487
  if (groupIsNoBorder && groupDescriptor.orientation === LayoutGroupOrientations.Vertical) {
467
- return (_jsx("div", { style: { width: '100%', border: 'none', padding: 0 }, children: children.map(child => renderLayoutItem(child, depth + 1, visited)) }));
488
+ return (_jsx("div", { style: { width: '100%', border: 'none', padding: 0 }, children: children.map(child => (_jsx(React.Fragment, { children: renderLayoutItem(child, depth + 1, visited) }, `child-${child.layoutItemID}`))) }));
468
489
  }
469
490
  if (!groupIsNoBorder && groupDescriptor.orientation === LayoutGroupOrientations.Vertical) {
470
491
  if (groupDescriptor.borderStyle == LayoutGroupBorderStyles.Group) {
471
- return (_jsxs("div", { style: { position: 'relative', border: '2px solid #CAD9EB', borderRadius: '3px', padding: '12px 6px 6px', margin: '10px', display: 'flex', flexDirection: 'column', flexWrap: 'wrap', gap: '3px', }, children: [_jsx("div", { style: { position: 'absolute', top: '-10px', left: '10px', padding: '0 8px', backgroundColor: '#fff', fontWeight: 600, fontSize: '1rem', color: TMColors.primaryColor, }, children: groupTitle }), children.map(child => renderLayoutItem(child, depth + 1, visited))] }));
492
+ return (_jsxs("div", { style: { position: 'relative', border: '2px solid #CAD9EB', borderRadius: '3px', padding: '12px 6px 6px', margin: '10px', display: 'flex', flexDirection: 'column', flexWrap: 'wrap', gap: '3px', }, children: [_jsx("div", { style: { position: 'absolute', top: '-10px', left: '10px', padding: '0 8px', backgroundColor: '#fff', fontWeight: 600, fontSize: '1rem', color: TMColors.primaryColor, }, children: groupTitle }), children.map(child => (_jsx(React.Fragment, { children: renderLayoutItem(child, depth + 1, visited) }, `child-${child.layoutItemID}`)))] }));
472
493
  }
473
494
  if (groupDescriptor.borderStyle == LayoutGroupBorderStyles.GroupBox || groupDescriptor.borderStyle == LayoutGroupBorderStyles.Tabbed) {
474
- return (_jsx(TMAccordion, { title: groupTitle, titleSize: "Small", children: children.map(child => renderLayoutItem(child, depth + 1, visited)) }));
495
+ return (_jsx(TMAccordion, { title: groupTitle, titleSize: "Small", children: children.map(child => (_jsx(React.Fragment, { children: renderLayoutItem(child, depth + 1, visited) }, `child-${child.layoutItemID}`))) }));
475
496
  }
476
497
  }
477
498
  if (groupDescriptor.orientation === LayoutGroupOrientations.Horizontal) {
478
499
  return (_jsx("div", { style: { display: 'flex', flexDirection: 'row', flexWrap: 'wrap', gap: '3px' }, children: groupDescriptor.borderStyle == LayoutGroupBorderStyles.GroupBox || groupDescriptor.borderStyle == LayoutGroupBorderStyles.Tabbed ?
479
- _jsx(TMAccordion, { title: groupTitle, titleSize: "Small", children: children.map(child => renderLayoutItem(child, depth + 1, visited)) }) :
500
+ _jsx(TMAccordion, { title: groupTitle, titleSize: "Small", children: children.map(child => (_jsx(React.Fragment, { children: renderLayoutItem(child, depth + 1, visited) }, `child-${child.layoutItemID}`))) }) :
480
501
  groupDescriptor.borderStyle == LayoutGroupBorderStyles.Group ?
481
502
  _jsxs("div", { style: { position: 'relative', border: '2px solid #CAD9EB', borderRadius: '3px', padding: '12px 6px 6px', margin: '10px', display: 'flex', flexDirection: 'column', flexWrap: 'wrap', gap: '3px', }, children: [_jsx("div", { style: { position: 'absolute', top: '-10px', left: '10px', padding: '0 8px', backgroundColor: '#fff', fontWeight: 600, fontSize: '1rem', color: TMColors.primaryColor, }, children: groupTitle }), children.map(child => (_jsx("div", { style: { flex: '1 1 0', minWidth: 0 }, children: renderLayoutItem(child, depth + 1, visited) }, child.layoutItemID)))] })
482
503
  :
@@ -484,7 +505,7 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
484
505
  }
485
506
  // Apply indentation only to subgroups (depth > 0), not to root groups
486
507
  const indentationPx = depth > 0 ? depth * 10 : 0;
487
- return (_jsx("div", { style: { paddingLeft: `${indentationPx}px` }, children: _jsx(TMAccordion, { title: groupTitle, defaultCollapsed: isCollapsed, titleSize: "Small", children: children.map(child => renderLayoutItem(child, depth + 1, visited)) }) }, `group-wrapper-${layoutItem.layoutItemID}`));
508
+ return (_jsx("div", { style: { paddingLeft: `${indentationPx}px` }, children: _jsx(TMAccordion, { title: groupTitle, defaultCollapsed: isCollapsed, titleSize: "Small", children: children.map(child => (_jsx(React.Fragment, { children: renderLayoutItem(child, depth + 1, visited) }, `child-${child.layoutItemID}`))) }) }, `group-wrapper-${layoutItem.layoutItemID}`));
488
509
  }
489
510
  // Check if this is a LayoutControlItem (metadata field)
490
511
  else if (layoutItem.type === LayoutItemTypes.LayoutControlItem && layoutItem.lcid) {
@@ -496,7 +517,8 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
496
517
  const parent = layout.items?.filter(p => p.layoutItemID === layoutItem.parentID);
497
518
  if (parent && parent.length > 0 && parent[0].type === LayoutItemTypes.LayoutGroup && parent[0].lgd) {
498
519
  const groupDescriptor = parent[0].lgd;
499
- if (groupDescriptor.borderStyle == LayoutGroupBorderStyles.Group)
520
+ if (groupDescriptor.borderStyle == LayoutGroupBorderStyles.Group
521
+ || groupDescriptor.borderStyle == LayoutGroupBorderStyles.NoBorder)
500
522
  isAccordion = false;
501
523
  }
502
524
  // Find the metadata value for this MID
@@ -515,7 +537,7 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
515
537
  };
516
538
  return (_jsx("div", { style: { width: '100%' }, children: (() => {
517
539
  const visited = new Set();
518
- return rootItems.map(item => renderLayoutItem(item, 0, visited));
540
+ return rootItems.map(item => (_jsx(React.Fragment, { children: renderLayoutItem(item, 0, visited) }, `root-item-${item.layoutItemID}`)));
519
541
  })() }));
520
542
  }, [layout, metadataValues, showCheckBoxes, showNullValueCheckBoxes, isReadOnly, dynDataListsToBeRefreshed, validationItems, selectedMID, isOpenDistinctValues, openChooserBySingleClick, metadataValuesOrig]);
521
543
  const renderForm = useMemo(() => {
@@ -533,7 +555,7 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
533
555
  }
534
556
  switch (currentDTD?.id) {
535
557
  case SystemTIDs.Drafts: return layoutDraft;
536
- // case SystemTIDs.Chronology: break;
558
+ case SystemTIDs.Chronology: return layoutChronology;
537
559
  case SystemTIDs.DSAttachs: return layoutDsAttachs;
538
560
  default:
539
561
  // Se è presente un layout personalizzato, usalo, altrimenti usa il rendering standard