@topconsultnpm/sdkui-react-beta 6.11.112 → 6.11.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/base/TMFileManager.d.ts +2 -11
- package/lib/components/base/TMFileManager.js +18 -15
- package/lib/components/base/TMFileManagerThumbnailItems.d.ts +14 -0
- package/lib/components/base/TMFileManagerThumbnailItems.js +165 -0
- package/lib/components/choosers/TMDynDataListItemChooser.js +4 -7
- package/lib/components/editors/TMHtmlContentDisplay.d.ts +6 -0
- package/lib/components/editors/TMHtmlContentDisplay.js +14 -0
- package/lib/components/editors/TMHtmlEditor.d.ts +29 -0
- package/lib/components/editors/TMHtmlEditor.js +66 -0
- package/lib/components/editors/TMMetadataEditor.d.ts +1 -1
- package/lib/components/editors/TMMetadataValues.js +38 -38
- package/lib/helper/SDKUI_Localizator.d.ts +4 -0
- package/lib/helper/SDKUI_Localizator.js +40 -0
- package/lib/stories/TMFileManager.stories.js +1 -1
- package/lib/stories/TMHtmlEditor.stories.d.ts +4 -0
- package/lib/stories/TMHtmlEditor.stories.js +16 -0
- package/package.json +1 -1
@@ -1,12 +1,3 @@
|
|
1
|
-
export interface TMWGsDraftThumbViewItemProps {
|
2
|
-
item: FileItem;
|
3
|
-
isSelected: boolean;
|
4
|
-
showId: boolean;
|
5
|
-
onClick: (id: number) => void;
|
6
|
-
onDoubleClick?: (file: FileItem) => void;
|
7
|
-
handleSelectedFiles?: (fileItems: Array<FileItem>) => void;
|
8
|
-
handleFocusedFile?: (fileItem: FileItem | undefined) => void;
|
9
|
-
}
|
10
1
|
export interface TMFileManagerContextMenuItem {
|
11
2
|
text: string;
|
12
3
|
icon: string;
|
@@ -51,6 +42,8 @@ export declare enum TMFileManagerPageSize {
|
|
51
42
|
Large = 100
|
52
43
|
}
|
53
44
|
export interface TMFileManagerProps {
|
45
|
+
/** Session User ID */
|
46
|
+
userID: number;
|
54
47
|
/** Determines the view mode of the file manager (Can be either 'thumbnails' or 'details') */
|
55
48
|
viewMode?: 'thumbnails' | 'details';
|
56
49
|
/** Represents the file system tree structure */
|
@@ -76,8 +69,6 @@ export interface TMFileManagerProps {
|
|
76
69
|
onDoubleClickHandler?: (fileItem: FileItem | undefined) => void;
|
77
70
|
/** Callback for handling drop file */
|
78
71
|
handleDropFileCallback?: (files: Array<File>) => void;
|
79
|
-
/** JSX element representing the thumbnail view item for a file or folder */
|
80
|
-
thumbnailsViewItemComponent?: (props: TMWGsDraftThumbViewItemProps) => JSX.Element;
|
81
72
|
/** Number of total founded */
|
82
73
|
dcmtsFound?: number;
|
83
74
|
}
|
@@ -11,6 +11,7 @@ import TMDataGrid from './TMDataGrid';
|
|
11
11
|
import { TMSplitterLayout } from './TMLayout';
|
12
12
|
import { DeviceType, useDeviceType } from './TMDeviceProvider';
|
13
13
|
import TMToolbarCard from './TMToolbarCard';
|
14
|
+
import { TMFileManagerThumbnailItems } from './TMFileManagerThumbnailItems';
|
14
15
|
export var TMFileManagerPageSize;
|
15
16
|
(function (TMFileManagerPageSize) {
|
16
17
|
TMFileManagerPageSize[TMFileManagerPageSize["Small"] = 30] = "Small";
|
@@ -19,7 +20,7 @@ export var TMFileManagerPageSize;
|
|
19
20
|
})(TMFileManagerPageSize || (TMFileManagerPageSize = {}));
|
20
21
|
const TMFileManager = (props) => {
|
21
22
|
// Destructure the treeFs prop to get the root file system
|
22
|
-
const { treeFs, selectedFolder, selectedFiles, focusedFile, handleSelectedFiles, handleFocusedFile, handleSelectedFolder, viewMode: initialViewMode, contextMenuItems, onDoubleClickHandler,
|
23
|
+
const { treeFs, selectedFolder, selectedFiles, focusedFile, userID, handleSelectedFiles, handleFocusedFile, handleSelectedFolder, viewMode: initialViewMode, contextMenuItems, onDoubleClickHandler, handleDropFileCallback, dcmtsFound } = props;
|
23
24
|
// State to manage the current view mode ('thumbnails' or 'details')
|
24
25
|
const [viewMode, setViewMode] = useState(initialViewMode ?? 'thumbnails');
|
25
26
|
// State to store the search text entered by the user
|
@@ -204,11 +205,20 @@ const TMFileManager = (props) => {
|
|
204
205
|
display: "flex",
|
205
206
|
flexGrow: 1,
|
206
207
|
height: "calc(100% - 40px)"
|
207
|
-
}, children: _jsxs(TMSplitterLayout, { direction: 'horizontal', showSeparator: true, separatorColor: 'transparent', separatorActiveColor: 'transparent', min: ['0', '0'], start: [isLeftPanelCollapsed ? '0%' : "50%", isLeftPanelCollapsed ? '100%' : "50%"], children: [_jsxs("div", { style: { height: "100%", width: "100%" }, onContextMenu: onTreeViewContextMenu, children: [_jsx(TreeView, { style: { marginTop: "10px" }, dataSource: treeViewData, displayExpr: "text", itemRender: renderTreeViewItem, onItemClick: handleTreeViewItemClick }), treeViewAnchor && _jsx(ContextMenu, { id: 'treeViewContextMenuDesktop', dataSource: menuItems.folder, target: treeViewAnchor, onHiding: closeTreeViewContextMenu })] }), _jsxs("div", { style: { backgroundColor: "#fff", width: "100%", height: "100%" }, children: [_jsxs(Toolbar, { style: { backgroundColor: '#f4f4f4', height: "40px", paddingLeft: "5px", paddingRight: '5px' }, children: [_jsx(ToolbarItem, { location: "before", children: _jsx(TMButton, { caption: viewMode === 'details' ? SDKUI_Localizator.PreviewView : SDKUI_Localizator.DetailsView, btnStyle: 'toolbar', color: 'primaryOutline', icon: viewMode === 'details' ? _jsx(IconDashboard, {}) : _jsx(IconList, {}), onClick: toggleViewMode }) }), _jsx(ToolbarItem, { location: "before", children: _jsx(TMSearchBar, { marginLeft: '0px', maxWidth: '160px', searchValue: searchText, onSearchValueChanged: (e) => handleSearchChange(e) }) })] }), _jsxs("div", { onDrop: handleDrop, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onContextMenu: onViewContextMenu, style: { width: "100%", height: "calc(100% - 40px)", border: isDragging ? '2px solid red' : '2px solid transparent' }, children: [viewMode === 'thumbnails' && _jsx(ThumbnailsView, { items: filteredFileItems, selectedFiles: selectedFiles, contextMenuItems: menuItems.file, handleSelectedFiles: handleSelectedFiles, handleFocusedFile: handleFocusedFile, onDoubleClickHandler: onDoubleClickHandler
|
208
|
+
}, children: _jsxs(TMSplitterLayout, { direction: 'horizontal', showSeparator: true, separatorColor: 'transparent', separatorActiveColor: 'transparent', min: ['0', '0'], start: [isLeftPanelCollapsed ? '0%' : "50%", isLeftPanelCollapsed ? '100%' : "50%"], children: [_jsxs("div", { style: { height: "100%", width: "100%" }, onContextMenu: onTreeViewContextMenu, children: [_jsx(TreeView, { style: { marginTop: "10px" }, dataSource: treeViewData, displayExpr: "text", itemRender: renderTreeViewItem, onItemClick: handleTreeViewItemClick }), treeViewAnchor && _jsx(ContextMenu, { id: 'treeViewContextMenuDesktop', dataSource: menuItems.folder, target: treeViewAnchor, onHiding: closeTreeViewContextMenu })] }), _jsxs("div", { style: { backgroundColor: "#fff", width: "100%", height: "100%" }, children: [_jsxs(Toolbar, { style: { backgroundColor: '#f4f4f4', height: "40px", paddingLeft: "5px", paddingRight: '5px' }, children: [_jsx(ToolbarItem, { location: "before", children: _jsx(TMButton, { caption: viewMode === 'details' ? SDKUI_Localizator.PreviewView : SDKUI_Localizator.DetailsView, btnStyle: 'toolbar', color: 'primaryOutline', icon: viewMode === 'details' ? _jsx(IconDashboard, {}) : _jsx(IconList, {}), onClick: toggleViewMode }) }), _jsx(ToolbarItem, { location: "before", children: _jsx(TMSearchBar, { marginLeft: '0px', maxWidth: '160px', searchValue: searchText, onSearchValueChanged: (e) => handleSearchChange(e) }) })] }), _jsxs("div", { onDrop: handleDrop, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onContextMenu: onViewContextMenu, style: { width: "100%", height: "calc(100% - 40px)", border: isDragging ? '2px solid red' : '2px solid transparent' }, children: [viewMode === 'thumbnails' && _jsx(ThumbnailsView, { userID: userID, items: filteredFileItems, selectedFiles: selectedFiles, searchText: searchText, contextMenuItems: menuItems.file, handleSelectedFiles: handleSelectedFiles, handleFocusedFile: handleFocusedFile, onDoubleClickHandler: onDoubleClickHandler }), viewMode === 'details' && _jsx(DetailsView, { items: filteredFileItems, contextMenuItems: menuItems.file, selectedFiles: selectedFiles, searchText: searchText, focusedFile: focusedFile, handleSelectedFiles: handleSelectedFiles, handleFocusedFile: handleFocusedFile, onDoubleClickHandler: onDoubleClickHandler }), viewAnchor && _jsx(ContextMenu, { id: 'fileContextMenuDesktop', dataSource: menuItems.file, target: viewAnchor, onHiding: closeViewContextMenu })] })] })] }, "TMWGs-panels-treeView") })] }), isMobile && _jsx("div", { style: { height: "100%", width: "100%" }, children: _jsxs(TMToolbarCard, { onBack: openDraftList ? onBackCallback : undefined, title: SDKUI_Localizator.Drafts, totalItems: dcmtsFound ?? 0, children: [_jsxs("div", { style: { display: openDraftList ? 'none' : 'block', transition: 'opacity 0.3s ease-in-out' }, children: [_jsx(TreeView, { style: { marginTop: "10px", }, dataSource: treeViewData, displayExpr: "text", itemRender: renderTreeViewItem, onItemClick: handleTreeViewItemClick }), treeViewAnchor && _jsx(ContextMenu, { id: 'treeViewContextMenuMobile', dataSource: menuItems.folder, target: treeViewAnchor, onHiding: closeTreeViewContextMenu })] }), _jsxs("div", { style: { backgroundColor: "#fff", width: "100%", height: "100%", display: openDraftList ? 'block' : 'none', transition: 'opacity 0.3s ease-in-out' }, children: [_jsxs(Toolbar, { style: { backgroundColor: '#f4f4f4', height: "40px", paddingLeft: "5px", paddingRight: '5px' }, children: [_jsx(ToolbarItem, { location: "before", children: _jsx(TMButton, { caption: viewMode === 'details' ? SDKUI_Localizator.PreviewView : SDKUI_Localizator.DetailsView, btnStyle: 'toolbar', color: 'primaryOutline', icon: viewMode === 'details' ? _jsx(IconDashboard, {}) : _jsx(IconList, {}), onClick: toggleViewMode }) }), _jsx(ToolbarItem, { location: "before", children: _jsx(TMSearchBar, { marginLeft: '0px', maxWidth: '160px', searchValue: searchText, onSearchValueChanged: (e) => handleSearchChange(e) }) })] }), _jsxs("div", { onDrop: handleDrop, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onContextMenu: onViewContextMenu, style: { width: "100%", height: "calc(100% - 40px)", border: isDragging ? '2px solid red' : '2px solid transparent' }, children: [viewMode === 'thumbnails' && _jsx(ThumbnailsView, { userID: userID, items: filteredFileItems, selectedFiles: selectedFiles, searchText: searchText, contextMenuItems: contextMenuItems?.file, handleSelectedFiles: handleSelectedFiles, handleFocusedFile: handleFocusedFile, onDoubleClickHandler: onDoubleClickHandler }), viewMode === 'details' && _jsx(DetailsView, { items: filteredFileItems, contextMenuItems: contextMenuItems?.file, selectedFiles: selectedFiles, searchText: searchText, focusedFile: focusedFile, handleSelectedFiles: handleSelectedFiles, handleFocusedFile: handleFocusedFile, onDoubleClickHandler: onDoubleClickHandler }), viewAnchor && _jsx(ContextMenu, { id: 'fileViewContextMenuMobile', dataSource: menuItems.file, target: viewAnchor, onHiding: closeViewContextMenu })] })] })] }) })] });
|
208
209
|
};
|
209
210
|
export default TMFileManager;
|
211
|
+
const highlightText = (text, searchText, isSelected) => {
|
212
|
+
if (!searchText)
|
213
|
+
return text;
|
214
|
+
const regex = new RegExp(`(${searchText})`, 'gi');
|
215
|
+
return text.split(regex).map((part, index) => regex.test(part) ? (_jsx("span", { style: { backgroundColor: isSelected ? '#6c9023' : 'yellow' }, children: part }, index)) : (part));
|
216
|
+
};
|
210
217
|
const DetailsView = (props) => {
|
211
|
-
const { items, contextMenuItems, focusedFile, selectedFiles, handleFocusedFile, handleSelectedFiles, onDoubleClickHandler } = props;
|
218
|
+
const { items, contextMenuItems, focusedFile, selectedFiles, searchText = '', handleFocusedFile, handleSelectedFiles, onDoubleClickHandler } = props;
|
219
|
+
const cellDefaultRender = useCallback((cellData) => {
|
220
|
+
return _jsx("div", { children: highlightText(cellData.value, searchText, false) });
|
221
|
+
}, [searchText]);
|
212
222
|
const cellExtRender = (cellData) => {
|
213
223
|
const data = cellData.data;
|
214
224
|
return _jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center' }, children: getFileIcon(data.ext, data.version) });
|
@@ -222,14 +232,14 @@ const DetailsView = (props) => {
|
|
222
232
|
return [
|
223
233
|
{ dataField: "id", caption: "ID", dataType: 'string', visible: false },
|
224
234
|
{ dataField: "ext", caption: SDKUI_Localizator.Extension, cellRender: cellExtRender },
|
225
|
-
{ dataField: "name", caption: SDKUI_Localizator.Name },
|
235
|
+
{ dataField: "name", caption: SDKUI_Localizator.Name, cellRender: cellDefaultRender },
|
226
236
|
{ dataField: "version", caption: SDKUI_Localizator.Version },
|
227
237
|
{ dataField: "size", caption: SDKUI_Localizator.Size, cellRender: (cellData) => formatBytes(cellData.data.size ?? 0) },
|
228
238
|
{ dataField: "updaterName", caption: SDKUI_Localizator.Author },
|
229
239
|
{ dataField: "lastUpdateTime", caption: SDKUI_Localizator.LastUpdateTime, dataType: 'datetime', format: 'dd/MM/yyyy HH:mm', cellRender: cellDatetimeRender },
|
230
240
|
{ dataField: "creationTime", caption: SDKUI_Localizator.CreationTime, dataType: 'datetime', format: 'dd/MM/yyyy HH:mm', cellRender: cellDatetimeRender },
|
231
241
|
];
|
232
|
-
}, []);
|
242
|
+
}, [searchText]);
|
233
243
|
// Handles selection change in the data grid
|
234
244
|
const onSelectionChanged = useCallback((e) => {
|
235
245
|
if (handleSelectedFiles) {
|
@@ -255,10 +265,10 @@ const DetailsView = (props) => {
|
|
255
265
|
e.items = contextMenuItems ? [...contextMenuItems] : [];
|
256
266
|
}
|
257
267
|
};
|
258
|
-
return (items && items.length > 0) ? (_jsx(TMDataGrid, { dataSource: items, dataColumns: dataColumns, focusedRowKey: focusedFile?.id, selectedRowKeys: selectedFiles?.map(file => file.id), onFocusedRowChanged: onFocusedRowChanged, onSelectionChanged: onSelectionChanged, onRowDblClick: onRowDblClick, onContextMenuPreparing: onContextMenuPreparing, showSearchPanel: false, showRowLines: SDKUI_Globals.dataGridShowRowLines, showColumnLines: SDKUI_Globals.dataGridShowColumnLines })) : _jsx("div", { style: { width: "100%", height: "100%", display: 'flex', justifyContent: 'center', alignItems: 'center', marginTop: '10px' }, children: SDKUI_Localizator.FolderIsEmpty });
|
268
|
+
return (items && items.length > 0) ? (_jsx(TMDataGrid, { dataSource: items ?? [], dataColumns: dataColumns, focusedRowKey: focusedFile?.id, selectedRowKeys: selectedFiles?.map(file => file.id), onFocusedRowChanged: onFocusedRowChanged, onSelectionChanged: onSelectionChanged, onRowDblClick: onRowDblClick, onContextMenuPreparing: onContextMenuPreparing, showSearchPanel: false, showRowLines: SDKUI_Globals.dataGridShowRowLines, showColumnLines: SDKUI_Globals.dataGridShowColumnLines })) : _jsx("div", { style: { width: "100%", height: "100%", display: 'flex', justifyContent: 'center', alignItems: 'center', marginTop: '10px' }, children: SDKUI_Localizator.FolderIsEmpty });
|
259
269
|
};
|
260
270
|
const ThumbnailsView = (props) => {
|
261
|
-
const { items, selectedFiles, handleSelectedFiles, handleFocusedFile, onDoubleClickHandler
|
271
|
+
const { items, selectedFiles, searchText = '', userID, handleSelectedFiles, handleFocusedFile, onDoubleClickHandler } = props;
|
262
272
|
const PAGE_SIZES = [TMFileManagerPageSize.Small, TMFileManagerPageSize.Medium, TMFileManagerPageSize.Large];
|
263
273
|
const initPageSize = TMFileManagerPageSize.Small;
|
264
274
|
const showPagination = (items?.length ?? 0) > initPageSize;
|
@@ -286,12 +296,5 @@ const ThumbnailsView = (props) => {
|
|
286
296
|
if (onDoubleClickHandler)
|
287
297
|
onDoubleClickHandler(item);
|
288
298
|
};
|
289
|
-
|
290
|
-
const defaultThumbnailViewItem = (props) => {
|
291
|
-
const { item, isSelected } = props;
|
292
|
-
return _jsx("div", { style: { padding: '10px', border: isSelected ? '2px solid blue' : '1px solid gray', marginBottom: '5px', cursor: 'pointer', }, children: _jsx("span", { children: item.name }) });
|
293
|
-
};
|
294
|
-
return items && items.length > 0 ? (_jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx(ScrollView, { width: "100%", height: showPagination ? "calc(100% - 50px)" : "100%", useNative: true, direction: 'both', children: _jsx("div", { style: { width: "100%", height: "100%" }, children: paginatedItems?.map(item => (_jsx("div", { children: thumbnailsViewItemComponent ?
|
295
|
-
thumbnailsViewItemComponent({ item, handleSelectedFiles, handleFocusedFile, isSelected: selectedFiles?.map(file => file.id).includes(item.id) ?? false, showId: false, onClick: () => handleItemClick(item), onDoubleClick: () => handleItemDoubleClick(item) }) :
|
296
|
-
defaultThumbnailViewItem({ item, handleSelectedFiles, handleFocusedFile, isSelected: selectedFiles?.map(file => file.id).includes(item.id) ?? false, showId: false, onClick: () => handleItemClick(item), onDoubleClick: () => handleItemDoubleClick(item) }) }, item.id))) }) }), showPagination && _jsx(Pagination, { height: "50px", showInfo: true, showNavigationButtons: true, allowedPageSizes: PAGE_SIZES, displayMode: 'compact', itemCount: items.length, pageIndex: pageIndex, pageSize: pageSize, onPageIndexChange: setPageIndex, onPageSizeChange: setPageSize })] })) : _jsx("div", { style: { width: "100%", height: "100%", display: 'flex', justifyContent: 'center', alignItems: 'center', marginTop: '10px' }, children: SDKUI_Localizator.FolderIsEmpty });
|
299
|
+
return items && items.length > 0 ? (_jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx(ScrollView, { width: "100%", height: showPagination ? "calc(100% - 50px)" : "100%", useNative: true, direction: 'both', children: _jsx(TMFileManagerThumbnailItems, { items: items, paginatedItems: paginatedItems, selectedFiles: selectedFiles, showId: false, userID: userID, searchText: searchText, handleFocusedFile: handleFocusedFile, handleSelectedFiles: handleSelectedFiles, onClick: handleItemClick, onDoubleClick: handleItemDoubleClick }) }), showPagination && _jsx(Pagination, { height: "50px", showInfo: true, showNavigationButtons: true, allowedPageSizes: PAGE_SIZES, displayMode: 'compact', itemCount: items.length, pageIndex: pageIndex, pageSize: pageSize, onPageIndexChange: setPageIndex, onPageSizeChange: setPageSize })] })) : _jsx("div", { style: { width: "100%", height: "100%", display: 'flex', justifyContent: 'center', alignItems: 'center', marginTop: '10px' }, children: SDKUI_Localizator.FolderIsEmpty });
|
297
300
|
};
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { FileItem } from './TMFileManager';
|
2
|
+
export interface TMFileManagerThumbnailItemsProps {
|
3
|
+
items: Array<FileItem>;
|
4
|
+
paginatedItems: Array<FileItem>;
|
5
|
+
selectedFiles: Array<FileItem> | undefined;
|
6
|
+
showId: boolean;
|
7
|
+
searchText: string;
|
8
|
+
userID: number;
|
9
|
+
onClick: (file: FileItem) => void;
|
10
|
+
onDoubleClick?: (file: FileItem) => void;
|
11
|
+
handleSelectedFiles?: (fileItems: Array<FileItem>) => void;
|
12
|
+
handleFocusedFile?: (fileItem: FileItem | undefined) => void;
|
13
|
+
}
|
14
|
+
export declare const TMFileManagerThumbnailItems: (props: TMFileManagerThumbnailItemsProps) => import("react/jsx-runtime").JSX.Element;
|
@@ -0,0 +1,165 @@
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
+
import { useEffect, useRef } from 'react';
|
3
|
+
import styled from 'styled-components';
|
4
|
+
import TMTooltip from './TMTooltip';
|
5
|
+
import { formatBytes, getFileIcon, Globalization, SDKUI_Localizator } from '../../helper';
|
6
|
+
const colors = {
|
7
|
+
BLACK: "#000000",
|
8
|
+
WHITE: "#fff",
|
9
|
+
LIGHT_GRAY: "#f9f9f9",
|
10
|
+
PRIMARY_BLUE: "#135596",
|
11
|
+
LIGHT_GREEN: "#c8e6c9",
|
12
|
+
LIGHT_YELLOW: "#fff9c4",
|
13
|
+
MEDIUM_GREEN: "#28a745",
|
14
|
+
};
|
15
|
+
const FileItemContainer = styled.div `
|
16
|
+
display: flex;
|
17
|
+
align-items: center;
|
18
|
+
justify-content: space-between;
|
19
|
+
padding: 10px;
|
20
|
+
border: 1px solid #ddd;
|
21
|
+
border-radius: 8px;
|
22
|
+
margin: 10px 5px;
|
23
|
+
background-color: ${({ $backgroundColor }) => $backgroundColor ?? colors.LIGHT_GRAY};
|
24
|
+
color: ${({ $textColor }) => $textColor ?? colors.BLACK};
|
25
|
+
position: relative;
|
26
|
+
min-width: 200px;
|
27
|
+
cursor: pointer;
|
28
|
+
&:hover {
|
29
|
+
background-color: ${({ $bgHoverColor }) => $bgHoverColor ?? '#e0e0e0'};
|
30
|
+
border-color: #999;
|
31
|
+
}
|
32
|
+
&:focus {
|
33
|
+
outline: none;
|
34
|
+
}
|
35
|
+
`;
|
36
|
+
const IconWrapper = styled.div `
|
37
|
+
display: flex;
|
38
|
+
flex-direction: column;
|
39
|
+
align-items: center;
|
40
|
+
margin-right: 10px;
|
41
|
+
font-size: 24px;
|
42
|
+
|
43
|
+
i {
|
44
|
+
font-size: 16px;
|
45
|
+
color: #555;
|
46
|
+
margin-top: 5px;
|
47
|
+
}
|
48
|
+
`;
|
49
|
+
const FileDetails = styled.div `
|
50
|
+
flex: 1;
|
51
|
+
display: flex;
|
52
|
+
flex-direction: column;
|
53
|
+
font-size: 14px;
|
54
|
+
`;
|
55
|
+
const FileName = styled.div `
|
56
|
+
font-size: 13px;
|
57
|
+
font-weight: bold;
|
58
|
+
word-break: break-word;
|
59
|
+
`;
|
60
|
+
const FileMeta = styled.div `
|
61
|
+
font-size: 12px;
|
62
|
+
`;
|
63
|
+
const Badge = styled.div `
|
64
|
+
width: 30px;
|
65
|
+
height: 30px;
|
66
|
+
border: 2px solid #28a745;
|
67
|
+
background-color: #28a745;
|
68
|
+
color: #fff;
|
69
|
+
font-size: 12px;
|
70
|
+
font-weight: bold;
|
71
|
+
padding: 5px 10px;
|
72
|
+
border-radius: 50%;
|
73
|
+
display: flex;
|
74
|
+
align-items: center;
|
75
|
+
justify-content: center;
|
76
|
+
margin-left: auto;
|
77
|
+
`;
|
78
|
+
const highlightText = (text, searchText, isSelected) => {
|
79
|
+
if (!searchText)
|
80
|
+
return text;
|
81
|
+
const regex = new RegExp(`(${searchText})`, 'gi');
|
82
|
+
return text.split(regex).map((part, index) => regex.test(part) ? (_jsx("span", { style: { backgroundColor: isSelected ? '#6c9023' : 'yellow' }, children: part }, index)) : (part));
|
83
|
+
};
|
84
|
+
export const TMFileManagerThumbnailItems = (props) => {
|
85
|
+
const { items, paginatedItems, selectedFiles, searchText, showId, userID, onClick, onDoubleClick, handleSelectedFiles, handleFocusedFile } = props;
|
86
|
+
// Ref to the container
|
87
|
+
const containerRef = useRef(null);
|
88
|
+
// Scroll the focused blog post into view
|
89
|
+
useEffect(() => {
|
90
|
+
if (selectedFiles && selectedFiles.length === 1 && containerRef.current) {
|
91
|
+
const selectedElement = document.getElementById(selectedFiles[0].id.toString());
|
92
|
+
if (selectedElement) {
|
93
|
+
selectedElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}, [selectedFiles]);
|
97
|
+
return _jsx("div", { style: { width: "100%", height: "100%" }, children: paginatedItems.map(item => {
|
98
|
+
let clickTimeout = null;
|
99
|
+
const isSelected = selectedFiles?.map(file => file.id).includes(item.id) ?? false;
|
100
|
+
const checkoutDate = item.checkoutDate;
|
101
|
+
const checkoutUsedId = item.checkOutUserID;
|
102
|
+
const editMode = checkoutDate && checkoutUsedId && userID && userID === checkoutUsedId;
|
103
|
+
const lockMode = checkoutDate && checkoutUsedId && userID && userID !== checkoutUsedId;
|
104
|
+
const textColor = isSelected ? colors.WHITE : colors.BLACK;
|
105
|
+
const backgroundColors = { editMode: colors.LIGHT_GREEN, lockMode: colors.LIGHT_YELLOW, };
|
106
|
+
let bgColor = isSelected ? colors.PRIMARY_BLUE : colors.LIGHT_GRAY;
|
107
|
+
let bgHoverColor = isSelected ? colors.PRIMARY_BLUE : "#e0e0e0";
|
108
|
+
if (editMode) {
|
109
|
+
bgColor = isSelected ? colors.PRIMARY_BLUE : backgroundColors.editMode;
|
110
|
+
bgHoverColor = isSelected ? colors.PRIMARY_BLUE : "#a5d6a7";
|
111
|
+
}
|
112
|
+
if (lockMode) {
|
113
|
+
bgColor = isSelected ? colors.PRIMARY_BLUE : backgroundColors.lockMode;
|
114
|
+
bgHoverColor = isSelected ? colors.PRIMARY_BLUE : "#fff59d";
|
115
|
+
}
|
116
|
+
const handleKeyDown = (event) => {
|
117
|
+
event.preventDefault();
|
118
|
+
if (event.key === 'ArrowDown' && selectedFiles && selectedFiles.length === 1) {
|
119
|
+
const currentIndex = items.findIndex(element => element.id === selectedFiles[0].id);
|
120
|
+
if (items[currentIndex + 1]) {
|
121
|
+
if (handleSelectedFiles)
|
122
|
+
handleSelectedFiles([items[currentIndex + 1]]);
|
123
|
+
}
|
124
|
+
;
|
125
|
+
}
|
126
|
+
};
|
127
|
+
const handleKeyUp = (event) => {
|
128
|
+
event.preventDefault();
|
129
|
+
if (event.key === 'ArrowUp' && selectedFiles && selectedFiles.length === 1) {
|
130
|
+
const currentIndex = items.findIndex(element => element.id === selectedFiles[0].id);
|
131
|
+
if (items[currentIndex - 1]) {
|
132
|
+
if (handleSelectedFiles)
|
133
|
+
handleSelectedFiles([items[currentIndex - 1]]);
|
134
|
+
}
|
135
|
+
;
|
136
|
+
}
|
137
|
+
};
|
138
|
+
const onDoubleClickHandler = () => {
|
139
|
+
if (clickTimeout) {
|
140
|
+
clearTimeout(clickTimeout);
|
141
|
+
clickTimeout = null;
|
142
|
+
}
|
143
|
+
if (onDoubleClick && item)
|
144
|
+
onDoubleClick(item);
|
145
|
+
};
|
146
|
+
const onClickHandler = () => {
|
147
|
+
if (clickTimeout) {
|
148
|
+
clearTimeout(clickTimeout);
|
149
|
+
clickTimeout = null;
|
150
|
+
}
|
151
|
+
else {
|
152
|
+
clickTimeout = setTimeout(() => {
|
153
|
+
if (onClick && item)
|
154
|
+
onClick(item);
|
155
|
+
}, 200);
|
156
|
+
}
|
157
|
+
};
|
158
|
+
const onContextMenu = () => {
|
159
|
+
if (handleFocusedFile)
|
160
|
+
handleFocusedFile(item);
|
161
|
+
};
|
162
|
+
const editLockTooltipText = _jsxs(_Fragment, { children: [_jsxs("div", { style: { textAlign: "center" }, children: [editMode && (_jsxs(_Fragment, { children: [_jsx("i", { style: { fontSize: "18px", color: colors.MEDIUM_GREEN, fontWeight: "bold" }, className: "dx-icon-edit" }), SDKUI_Localizator.CurrentUserExtract] })), lockMode && (_jsxs(_Fragment, { children: [_jsx("i", { style: { fontSize: "18px", color: colors.MEDIUM_GREEN, fontWeight: "bold" }, className: "dx-icon-lock" }), SDKUI_Localizator.ExtractedFromOtherUser] }))] }), _jsx("hr", {}), _jsxs("div", { style: { textAlign: "left" }, children: [_jsxs("ul", { children: [_jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.ExtractedBy }), ": ", item.checkOutUserName ?? '-', " (ID: ", item.checkOutUserID, ")"] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.ExtractedOn }), ": ", Globalization.getDateTimeDisplayValue(item.checkoutDate?.toString())] })] }), _jsx("hr", {}), _jsx("ul", { children: _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.Version }), ": ", item.version ?? 1] }) }), _jsx("hr", {}), _jsxs("ul", { children: [_jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.Type }), ": ", item.ext] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.CreationTime }), ": ", Globalization.getDateTimeDisplayValue(item.creationTime?.toString())] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.LastUpdateTime }), ": ", Globalization.getDateTimeDisplayValue(item.lastUpdateTime?.toString())] })] })] })] });
|
163
|
+
return _jsxs(FileItemContainer, { ref: containerRef, id: item.id.toString(), "$backgroundColor": bgColor, "$bgHoverColor": bgHoverColor, "$textColor": textColor, onDoubleClick: onDoubleClickHandler, onContextMenu: onContextMenu, onClick: onClickHandler, tabIndex: 0, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, children: [_jsxs(IconWrapper, { children: [getFileIcon(item.ext, item.version), editMode && _jsx(TMTooltip, { content: editLockTooltipText, children: _jsx("i", { style: { fontSize: "18px", color: colors.MEDIUM_GREEN, fontWeight: "bold" }, className: "dx-icon-edit" }) }), lockMode && _jsx(TMTooltip, { content: editLockTooltipText, children: _jsx("i", { style: { fontSize: "18px", color: colors.MEDIUM_GREEN, fontWeight: "bold" }, className: "dx-icon-lock" }) })] }), _jsxs(FileDetails, { children: [_jsx(FileName, { children: showId ? highlightText(`(${item.id}) ${item.name}`, searchText, isSelected) : highlightText(item.name, searchText, isSelected) }), _jsx(FileMeta, { children: formatBytes(item.size ?? 0) })] }), item.version && _jsx(Badge, { children: _jsx(TMTooltip, { content: SDKUI_Localizator.Version, children: item.version }) })] }, "item-file-manager-" + item.id);
|
164
|
+
}) });
|
165
|
+
};
|
@@ -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,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
|
10
|
+
containerElement?: Element;
|
11
11
|
disabled?: boolean;
|
12
12
|
validationItems?: ValidationItem[];
|
13
13
|
isLexProt?: number;
|
@@ -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 (
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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 (
|
92
|
+
if (mvdList.length <= 0)
|
93
93
|
return [];
|
94
94
|
let dynDLToBeRefreshed = [];
|
95
|
-
for (const m of
|
95
|
+
for (const m of mvdList) {
|
96
96
|
if (!m.value)
|
97
97
|
continue;
|
98
|
-
let data = await getDataDynDataListsToBeRefreshedAsync(tid, m.mid,
|
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,
|
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 (
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
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
|
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:
|
237
|
+
height: 100%;
|
238
238
|
overflow: auto;
|
239
239
|
padding: 0 10px 10px 10px;
|
240
240
|
`;
|
@@ -68,6 +68,7 @@ export declare class SDKUI_Localizator {
|
|
68
68
|
static get Create(): "Erstellen" | "Create" | "Crear" | "Créer" | "Criar" | "Crea";
|
69
69
|
static get CreationTime(): "Erstellungsdatum" | "Creation Time" | "Fecha creación" | "Date de création" | "Data de criação" | "Data creazione";
|
70
70
|
static get CultureID(): "Sprache" | "Language" | "Idioma" | "Lingue" | "Língua" | "Lingua";
|
71
|
+
static get CurrentUserExtract(): string;
|
71
72
|
static get Date(): "Datum" | "Date" | "fecha" | "Data";
|
72
73
|
static get Date_Modified(): "Datum geändert" | "Date Modified" | "Fecha modificada" | "Date modifiée" | "Data modificada" | "Data modificata";
|
73
74
|
static get DcmtCount(): "Anzahl der Dokumente" | "Number of documents" | "Número de documentos" | "Nombre de documents" | "Numero documenti";
|
@@ -106,6 +107,9 @@ export declare class SDKUI_Localizator {
|
|
106
107
|
static get EnterValue(): "Geben Sie einen Wert ein" | "Enter a value" | "Introducir un valor" | "Entrez une valeur" | "Digite um valor" | "Inserire un valore";
|
107
108
|
static get Error(): "Fehler" | "Error" | "Erreur" | "Erro" | "Errore";
|
108
109
|
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.";
|
110
|
+
static get ExtractedBy(): "Ausgezogen von" | "Extracted by" | "Extraído por" | "Extrait par" | "Estratto da";
|
111
|
+
static get ExtractedFromOtherUser(): string;
|
112
|
+
static get ExtractedOn(): "Ausgezogen am" | "Extracted on" | "Extraído el" | "Extrait le" | "Extraído em" | "Estratto il";
|
109
113
|
static get EvaluateResult(): "Bewerten Sie das Ergebnis" | "Evaluate result" | "Valorar el resultado" | "Évalue les résultats" | "Avalia os resultados" | "Valuta il risultato";
|
110
114
|
static get ExpertMode(): "Expertenmodus" | "Expert mode" | "Modo experto" | "Mode expert" | "Modo especialista" | "Modalità esperto";
|
111
115
|
static get Export(): "Exportieren" | "Export" | "Exportar" | "Exporter" | "Esporta";
|
@@ -629,6 +629,16 @@ export class SDKUI_Localizator {
|
|
629
629
|
default: return "Lingua";
|
630
630
|
}
|
631
631
|
}
|
632
|
+
static get CurrentUserExtract() {
|
633
|
+
switch (this._cultureID) {
|
634
|
+
case CultureIDs.De_DE: return "Auszug aus dem aktuellen Benutzer und änderbar";
|
635
|
+
case CultureIDs.En_US: return "Extracted from the current user and editable";
|
636
|
+
case CultureIDs.Es_ES: return "Extraído del usuario actual y editable";
|
637
|
+
case CultureIDs.Fr_FR: return "Extrait de l'utilisateur actuel et modifiable";
|
638
|
+
case CultureIDs.Pt_PT: return "Extraído do usuário atual e editável";
|
639
|
+
default: return "Estratto dall'utente corrente e modificabile";
|
640
|
+
}
|
641
|
+
}
|
632
642
|
static get Date() {
|
633
643
|
switch (this._cultureID) {
|
634
644
|
case CultureIDs.De_DE: return "Datum";
|
@@ -1021,6 +1031,36 @@ export class SDKUI_Localizator {
|
|
1021
1031
|
default: return "Errore durante l'analisi del contenuto del file. Assicurati che il file sia nel formato corretto.";
|
1022
1032
|
}
|
1023
1033
|
}
|
1034
|
+
static get ExtractedBy() {
|
1035
|
+
switch (this._cultureID) {
|
1036
|
+
case CultureIDs.De_DE: return "Ausgezogen von";
|
1037
|
+
case CultureIDs.En_US: return "Extracted by";
|
1038
|
+
case CultureIDs.Es_ES: return "Extraído por";
|
1039
|
+
case CultureIDs.Fr_FR: return "Extrait par";
|
1040
|
+
case CultureIDs.Pt_PT: return "Extraído por";
|
1041
|
+
default: return "Estratto da";
|
1042
|
+
}
|
1043
|
+
}
|
1044
|
+
static get ExtractedFromOtherUser() {
|
1045
|
+
switch (this._cultureID) {
|
1046
|
+
case CultureIDs.De_DE: return "Auszug von einem anderen Benutzer und nicht bearbeitbar";
|
1047
|
+
case CultureIDs.En_US: return "Extracted from another user and not editable";
|
1048
|
+
case CultureIDs.Es_ES: return "Extraído de otro usuario y no editable";
|
1049
|
+
case CultureIDs.Fr_FR: return "Extrait d'un autre utilisateur et non modifiable";
|
1050
|
+
case CultureIDs.Pt_PT: return "Extraído de outro usuário e não editável";
|
1051
|
+
default: return "Estratto da un altro utente e non modificabile";
|
1052
|
+
}
|
1053
|
+
}
|
1054
|
+
static get ExtractedOn() {
|
1055
|
+
switch (this._cultureID) {
|
1056
|
+
case CultureIDs.De_DE: return "Ausgezogen am";
|
1057
|
+
case CultureIDs.En_US: return "Extracted on";
|
1058
|
+
case CultureIDs.Es_ES: return "Extraído el";
|
1059
|
+
case CultureIDs.Fr_FR: return "Extrait le";
|
1060
|
+
case CultureIDs.Pt_PT: return "Extraído em";
|
1061
|
+
default: return "Estratto il";
|
1062
|
+
}
|
1063
|
+
}
|
1024
1064
|
static get EvaluateResult() {
|
1025
1065
|
switch (this._cultureID) {
|
1026
1066
|
case CultureIDs.De_DE: return "Bewerten Sie das Ergebnis";
|
@@ -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 = {};
|