@topconsultnpm/sdkui-react 6.19.0-dev1.9 → 6.19.0-dev2.10
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/NewComponents/ContextMenu/TMContextMenu.d.ts +4 -0
- package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +187 -0
- package/lib/components/NewComponents/ContextMenu/hooks.d.ts +11 -0
- package/lib/components/NewComponents/ContextMenu/hooks.js +48 -0
- package/lib/components/NewComponents/ContextMenu/index.d.ts +2 -0
- package/lib/components/NewComponents/ContextMenu/index.js +1 -0
- package/lib/components/NewComponents/ContextMenu/styles.d.ts +27 -0
- package/lib/components/NewComponents/ContextMenu/styles.js +308 -0
- package/lib/components/NewComponents/ContextMenu/types.d.ts +26 -0
- package/lib/components/NewComponents/ContextMenu/types.js +1 -0
- package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.d.ts +4 -0
- package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +370 -0
- package/lib/components/NewComponents/FloatingMenuBar/index.d.ts +2 -0
- package/lib/components/NewComponents/FloatingMenuBar/index.js +2 -0
- package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +38 -0
- package/lib/components/NewComponents/FloatingMenuBar/styles.js +267 -0
- package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +30 -0
- package/lib/components/NewComponents/FloatingMenuBar/types.js +1 -0
- package/lib/components/NewComponents/Notification/Notification.d.ts +4 -0
- package/lib/components/NewComponents/Notification/Notification.js +60 -0
- package/lib/components/NewComponents/Notification/NotificationContainer.d.ts +8 -0
- package/lib/components/NewComponents/Notification/NotificationContainer.js +33 -0
- package/lib/components/NewComponents/Notification/index.d.ts +2 -0
- package/lib/components/NewComponents/Notification/index.js +2 -0
- package/lib/components/NewComponents/Notification/styles.d.ts +21 -0
- package/lib/components/NewComponents/Notification/styles.js +180 -0
- package/lib/components/NewComponents/Notification/types.d.ts +18 -0
- package/lib/components/NewComponents/Notification/types.js +1 -0
- package/lib/components/base/Styled.d.ts +1 -0
- package/lib/components/base/Styled.js +40 -0
- package/lib/components/base/TMCustomButton.d.ts +11 -0
- package/lib/components/base/TMCustomButton.js +63 -0
- package/lib/components/base/TMFileManagerDataGridView.js +4 -1
- package/lib/components/base/TMLayout.d.ts +2 -1
- package/lib/components/base/TMLayout.js +2 -2
- package/lib/components/base/TMPopUp.js +5 -18
- package/lib/components/base/TMTreeView.js +3 -2
- package/lib/components/editors/TMHtmlEditor.d.ts +5 -0
- package/lib/components/editors/TMHtmlEditor.js +72 -12
- package/lib/components/editors/TMMetadataValues.js +90 -40
- package/lib/components/features/archive/TMArchive.d.ts +10 -0
- package/lib/components/features/archive/TMArchive.js +56 -25
- package/lib/components/features/blog/TMBlogCommentForm.d.ts +4 -4
- package/lib/components/features/blog/TMBlogCommentForm.js +76 -51
- package/lib/components/features/documents/TMDcmtBlog.d.ts +15 -0
- package/lib/components/features/documents/TMDcmtBlog.js +21 -33
- package/lib/components/features/documents/TMDcmtForm.d.ts +17 -3
- package/lib/components/features/documents/TMDcmtForm.js +205 -46
- package/lib/components/features/documents/TMDcmtTasks.d.ts +13 -0
- package/lib/components/features/documents/TMDcmtTasks.js +24 -0
- package/lib/components/features/documents/TMDragDropOverlay.js +2 -1
- package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +8 -1
- package/lib/components/features/documents/TMMasterDetailDcmts.js +6 -6
- package/lib/components/features/documents/TMRelationViewer.d.ts +53 -3
- package/lib/components/features/documents/TMRelationViewer.js +232 -85
- package/lib/components/features/search/TMSearch.d.ts +10 -1
- package/lib/components/features/search/TMSearch.js +14 -5
- package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -1
- package/lib/components/features/search/TMSearchQueryPanel.js +36 -7
- package/lib/components/features/search/TMSearchResult.d.ts +10 -1
- package/lib/components/features/search/TMSearchResult.js +140 -422
- package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +2 -2
- package/lib/components/features/search/TMSearchResultsMenuItems.js +40 -15
- package/lib/components/features/tasks/TMTaskForm.d.ts +38 -0
- package/lib/components/features/tasks/TMTaskForm.js +386 -0
- package/lib/components/features/tasks/TMTasksAgenda.d.ts +17 -0
- package/lib/components/features/tasks/TMTasksAgenda.js +107 -0
- package/lib/components/features/tasks/TMTasksCalendar.d.ts +21 -0
- package/lib/components/features/tasks/TMTasksCalendar.js +240 -0
- package/lib/components/features/tasks/TMTasksHeader.d.ts +14 -0
- package/lib/components/features/tasks/TMTasksHeader.js +37 -0
- package/lib/components/features/tasks/TMTasksPanelContent.d.ts +20 -0
- package/lib/components/features/tasks/TMTasksPanelContent.js +65 -0
- package/lib/components/features/tasks/TMTasksUtils.d.ts +132 -0
- package/lib/components/features/tasks/TMTasksUtils.js +634 -0
- package/lib/components/features/tasks/TMTasksUtilsView.d.ts +39 -0
- package/lib/components/features/tasks/TMTasksUtilsView.js +118 -0
- package/lib/components/features/tasks/TMTasksView.d.ts +40 -0
- package/lib/components/features/tasks/TMTasksView.js +560 -0
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +3 -1
- package/lib/components/features/workflow/TMWorkflowPopup.js +19 -6
- package/lib/components/features/workflow/diagram/RecipientList.js +4 -3
- package/lib/components/forms/Login/Chooser.js +1 -1
- package/lib/components/forms/TMChooserForm.d.ts +1 -1
- package/lib/components/forms/TMChooserForm.js +2 -2
- package/lib/components/grids/TMBlogAttachments.d.ts +42 -0
- package/lib/components/grids/TMBlogAttachments.js +43 -0
- package/lib/components/grids/TMBlogHeader.d.ts +31 -0
- package/lib/components/grids/TMBlogHeader.js +41 -0
- package/lib/components/grids/{TMBlogs.d.ts → TMBlogsPost.d.ts} +42 -58
- package/lib/components/grids/TMBlogsPost.js +628 -0
- package/lib/components/grids/{TMBlogsUtils.d.ts → TMBlogsPostUtils.d.ts} +61 -47
- package/lib/components/grids/{TMBlogsUtils.js → TMBlogsPostUtils.js} +146 -124
- package/lib/components/index.d.ts +14 -1
- package/lib/components/index.js +15 -1
- package/lib/components/layout/panelManager/TMPanelManagerContext.js +7 -0
- package/lib/components/settings/SettingsAppearance.js +9 -1
- package/lib/components/viewers/TMTidViewer.js +20 -2
- package/lib/css/tm-sdkui.css +1 -1
- package/lib/helper/SDKUI_Globals.d.ts +4 -1
- package/lib/helper/SDKUI_Globals.js +10 -1
- package/lib/helper/SDKUI_Localizator.d.ts +87 -4
- package/lib/helper/SDKUI_Localizator.js +868 -25
- package/lib/helper/TMCustomSearchBar.d.ts +8 -0
- package/lib/helper/TMCustomSearchBar.js +54 -0
- package/lib/helper/TMIcons.d.ts +3 -0
- package/lib/helper/TMIcons.js +9 -0
- package/lib/helper/TMImageLibrary.d.ts +3 -2
- package/lib/helper/TMImageLibrary.js +230 -230
- package/lib/helper/TMToppyMessage.d.ts +7 -0
- package/lib/helper/TMToppyMessage.js +42 -0
- package/lib/helper/TMUtils.d.ts +10 -1
- package/lib/helper/TMUtils.js +42 -1
- package/lib/helper/dcmtsHelper.d.ts +2 -0
- package/lib/helper/dcmtsHelper.js +18 -0
- package/lib/helper/helpers.js +1 -0
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/hooks/useRelatedDocuments.d.ts +72 -0
- package/lib/hooks/useRelatedDocuments.js +655 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/ts/types.d.ts +14 -0
- package/lib/ts/types.js +15 -0
- package/lib/utils/theme.d.ts +1 -0
- package/lib/utils/theme.js +1 -0
- package/package.json +7 -7
- package/lib/components/grids/TMBlogs.js +0 -721
- package/lib/stories/TMButton.stories.d.ts +0 -4
- package/lib/stories/TMButton.stories.js +0 -29
- package/lib/stories/TMDataGrid.stories.d.ts +0 -9
- package/lib/stories/TMDataGrid.stories.js +0 -310
- package/lib/stories/TMHtmlContentDisplay.stories.d.ts +0 -6
- package/lib/stories/TMHtmlContentDisplay.stories.js +0 -45
- package/lib/stories/TMHtmlEditor.stories.d.ts +0 -6
- package/lib/stories/TMHtmlEditor.stories.js +0 -49
- package/lib/stories/TMIcons.stories.d.ts +0 -4
- package/lib/stories/TMIcons.stories.js +0 -13
- package/lib/stories/TMSDKUI_Localizator.stories.d.ts +0 -4
- package/lib/stories/TMSDKUI_Localizator.stories.js +0 -123
- package/lib/stories/TMStoriesUtils.d.ts +0 -1
- package/lib/stories/TMStoriesUtils.js +0 -10
- package/lib/stories/TMUserAvatar.stories.d.ts +0 -6
- package/lib/stories/TMUserAvatar.stories.js +0 -20
|
@@ -4,8 +4,35 @@ import HtmlEditor, { Toolbar, Item } from 'devextreme-react/html-editor';
|
|
|
4
4
|
import ReactDOM from 'react-dom';
|
|
5
5
|
import { SDKUI_Localizator } from '../../helper';
|
|
6
6
|
import TMVilViewer from '../base/TMVilViewer';
|
|
7
|
+
import { TMMessageBoxManager, ButtonNames } from '../base/TMPopUp';
|
|
8
|
+
import TMTooltip from '../base/TMTooltip';
|
|
9
|
+
import { useDeviceType, DeviceType } from '../base/TMDeviceProvider';
|
|
10
|
+
export const sanitizeAndFormatComment = (raw = "") => {
|
|
11
|
+
if (!raw)
|
|
12
|
+
return "";
|
|
13
|
+
let cleanComment = raw
|
|
14
|
+
// Simplify dx-mention markup - replace with just @username
|
|
15
|
+
.replace(/<span class="dx-mention"[^>]*>\uFEFF?<span[^>]*><span>@<\/span>([^<]+)<\/span>\uFEFF?<\/span>/gi, '@$1')
|
|
16
|
+
// Replace </p> with '' only if followed by <ol> or <ul>
|
|
17
|
+
.replace(/<\/p>(?=\s*<(ol|ul)>)/gi, '')
|
|
18
|
+
// Replace all other </p> with '\r\n'
|
|
19
|
+
.replace(/<\/p>/gi, '\r\n')
|
|
20
|
+
// Remove all <p> tags
|
|
21
|
+
.replace(/<p>/gi, '')
|
|
22
|
+
// Remove all <br> tags
|
|
23
|
+
.replace(/<br>/gi, '')
|
|
24
|
+
// Trim whitespace
|
|
25
|
+
.trim();
|
|
26
|
+
// Remove dangerous HTML elements
|
|
27
|
+
cleanComment = cleanComment.replace(/<(script|iframe|embed|object|link|style|img|video|audio|svg|form|input|button|textarea|select|pre|function)[^>]*>/gi, '');
|
|
28
|
+
return cleanComment;
|
|
29
|
+
};
|
|
7
30
|
const TMHtmlEditor = (props) => {
|
|
8
|
-
const { width = "100%", height = "100%", initialMarkup = "", mentionsConfig, onValueChanged, validationItems = [], isEditorEnabled: isEditorEnabledProp = false, toolbarMode = 'compact', autoFocus = false } = props;
|
|
31
|
+
const { width = "100%", height = "100%", initialMarkup = "", mentionsConfig, onValueChanged, validationItems = [], isEditorEnabled: isEditorEnabledProp = false, toolbarMode = 'compact', autoFocus = false, maxLength = 1000, showCount = true, } = props;
|
|
32
|
+
// Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
|
|
33
|
+
const deviceType = useDeviceType();
|
|
34
|
+
// This avoids unnecessary re-renders by only recalculating when deviceType changes.
|
|
35
|
+
let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
|
|
9
36
|
// Ref for HtmlEditor instance
|
|
10
37
|
const editorRef = useRef(null);
|
|
11
38
|
// State for editor enable/disable
|
|
@@ -14,13 +41,15 @@ const TMHtmlEditor = (props) => {
|
|
|
14
41
|
const [markup, setMarkup] = useState(initialMarkup);
|
|
15
42
|
// State to track the position (x, y coordinates) where the custom context menu should be displayed.
|
|
16
43
|
const [contextMenuPos, setContextMenuPos] = useState(null);
|
|
17
|
-
// State to
|
|
18
|
-
const [
|
|
44
|
+
// State to track remaining characters
|
|
45
|
+
const [charactersRemaining, setCharactersRemaining] = useState(maxLength - initialMarkup.length);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const cleanedMarkup = sanitizeAndFormatComment(markup);
|
|
48
|
+
setCharactersRemaining(maxLength - cleanedMarkup.length);
|
|
49
|
+
}, [markup, maxLength]);
|
|
19
50
|
// Function to read text from the clipboard, format it, and paste into the Quill editor
|
|
20
51
|
const pasteFromClipboard = async () => {
|
|
21
52
|
try {
|
|
22
|
-
// Set flag to indicate paste operation is in progress
|
|
23
|
-
setIsPasting(true);
|
|
24
53
|
// Read plain text from the clipboard asynchronously
|
|
25
54
|
let text = await navigator.clipboard.readText();
|
|
26
55
|
text = '<p>' + text.replace(/\r\n/g, '</p><p>') + '</p>';
|
|
@@ -52,10 +81,6 @@ const TMHtmlEditor = (props) => {
|
|
|
52
81
|
// Log any errors that might occur during clipboard access or pasting
|
|
53
82
|
console.warn('Clipboard paste failed:', err);
|
|
54
83
|
}
|
|
55
|
-
finally {
|
|
56
|
-
// Reset paste state after a short delay to restore UI state
|
|
57
|
-
setTimeout(() => setIsPasting(false), 500);
|
|
58
|
-
}
|
|
59
84
|
};
|
|
60
85
|
useEffect(() => {
|
|
61
86
|
const handleKeyDown = (e) => {
|
|
@@ -116,7 +141,7 @@ const TMHtmlEditor = (props) => {
|
|
|
116
141
|
}, [autoFocus]);
|
|
117
142
|
// Memoized check for validation errors
|
|
118
143
|
const hasValidationErrors = useMemo(() => {
|
|
119
|
-
return
|
|
144
|
+
return validationItems && validationItems.length > 0;
|
|
120
145
|
}, [validationItems]);
|
|
121
146
|
// Handler function triggered by the context menu's "Paste" action
|
|
122
147
|
const handlePaste = async () => {
|
|
@@ -125,9 +150,44 @@ const TMHtmlEditor = (props) => {
|
|
|
125
150
|
// Close the custom context menu after pasting
|
|
126
151
|
setContextMenuPos(null);
|
|
127
152
|
};
|
|
128
|
-
return (_jsxs("div", { style: {
|
|
153
|
+
return (_jsxs("div", { style: {
|
|
154
|
+
height: height,
|
|
155
|
+
width: width
|
|
156
|
+
}, children: [_jsx("div", { className: "custom-mentions-wrapper", onContextMenu: handleContextMenu, style: {
|
|
157
|
+
borderWidth: '1px',
|
|
158
|
+
borderStyle: 'solid',
|
|
159
|
+
borderColor: hasValidationErrors ? "red" : "#e0e0e0 #e0e0e0 #616161",
|
|
160
|
+
width: "100%",
|
|
161
|
+
height: `calc(100% - ${showCount ? 15 : 0}px - ${validationItems.length > 0 ? 15 : 0}px)`,
|
|
162
|
+
}, children: _jsx(HtmlEditor, { ref: editorRef, placeholder: SDKUI_Localizator.TypeAMessage + "...", width: "100%", height: "100%", value: markup, onValueChange: onValueChangeCallback, mentions: mentionsConfig, style: { overflow: 'hidden', outline: "none", fontSize: '1rem' }, children: isEditorEnabled && (toolbarMode === 'compact' ?
|
|
129
163
|
_jsxs(Toolbar, { multiline: false, children: [_jsx(Item, { name: "undo" }), _jsx(Item, { name: "redo" }), _jsx(Item, { name: "separator" }), _jsx(Item, { name: "bold" }), _jsx(Item, { name: "italic" }), _jsx(Item, { name: "strike" }), _jsx(Item, { name: "underline" }), _jsx(Item, { name: "separator" }), _jsx(Item, { name: "orderedList" }), _jsx(Item, { name: "bulletList" })] }) :
|
|
130
|
-
_jsxs(Toolbar, { 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: "strike" }), _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: "color" }), _jsx(Item, { name: "background" }), _jsx(Item, { name: "separator" }), _jsx(Item, { name: "link" }), _jsx(Item, { name: "image" }), _jsx(Item, { name: "separator" })] })) }) }),
|
|
164
|
+
_jsxs(Toolbar, { 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: "strike" }), _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: "color" }), _jsx(Item, { name: "background" }), _jsx(Item, { name: "separator" }), _jsx(Item, { name: "link" }), _jsx(Item, { name: "image" }), _jsx(Item, { name: "separator" })] })) }) }), showCount ? ((() => {
|
|
165
|
+
const cleanedMarkup = sanitizeAndFormatComment(markup);
|
|
166
|
+
const showInfoIcon = charactersRemaining !== maxLength;
|
|
167
|
+
return (_jsxs("div", { style: {
|
|
168
|
+
display: 'flex',
|
|
169
|
+
alignItems: 'center',
|
|
170
|
+
justifyContent: 'flex-end',
|
|
171
|
+
fontSize: 12,
|
|
172
|
+
color: '#6c757d',
|
|
173
|
+
marginTop: 4,
|
|
174
|
+
gap: 4,
|
|
175
|
+
}, children: [`${Math.max(charactersRemaining, 0)} ${SDKUI_Localizator.CharactersRemaining}`, showInfoIcon && (_jsx(TMTooltip, { content: 'Markup HTML', children: _jsx("span", { className: "dx-icon-codeblock", style: { fontSize: 22, cursor: 'pointer' }, onClick: () => {
|
|
176
|
+
TMMessageBoxManager.show({
|
|
177
|
+
title: 'Markup HTML',
|
|
178
|
+
initialWidth: !isMobile ? '700px' : undefined,
|
|
179
|
+
message: (_jsx("pre", { style: {
|
|
180
|
+
whiteSpace: 'pre-wrap',
|
|
181
|
+
background: '#f5f5f5',
|
|
182
|
+
padding: '12px',
|
|
183
|
+
borderRadius: '6px',
|
|
184
|
+
}, children: cleanedMarkup })),
|
|
185
|
+
resizable: true,
|
|
186
|
+
showToppy: false,
|
|
187
|
+
buttons: [ButtonNames.OK],
|
|
188
|
+
});
|
|
189
|
+
} }) }))] }));
|
|
190
|
+
})()) : null, validationItems.length > 0 && _jsx(TMVilViewer, { vil: validationItems }), contextMenuPos &&
|
|
131
191
|
ReactDOM.createPortal(_jsxs("div", { style: {
|
|
132
192
|
position: 'fixed',
|
|
133
193
|
top: contextMenuPos.y,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useEffect, useState } from "react";
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
3
3
|
import styled from "styled-components";
|
|
4
4
|
import { AccessLevels, DcmtTypeListCacheService, LayoutItemTypes, LayoutModes, MetadataDataDomains, MetadataDataTypes, SDK_Globals, SystemMIDsAsNumber, SystemTIDs, TemplateTIDs, WorkItemMetadataNames } from '@topconsultnpm/sdk-ts';
|
|
5
5
|
import { IconUndo, IconPencil, IconFunction, IconMenuVertical, IconDataList, SDKUI_Localizator, IconNull, stringIsNullOrEmpty, deepCompare, SDKUI_Globals, IconDcmtTypeSys } from "../../helper";
|
|
@@ -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 } from "../../ts";
|
|
13
|
+
import { DraftsMIDs, DSAttachsMIDs } from "../../ts";
|
|
14
14
|
import { TMNothingToShow } from "../features/documents/TMDcmtPreview";
|
|
15
15
|
import TMAccordion from "../base/TMAccordion";
|
|
16
16
|
export var ShowCheckBoxesMode;
|
|
@@ -33,7 +33,7 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
33
33
|
const [selectedItem, setSelectedItem] = useState(undefined);
|
|
34
34
|
const [prevMetadataValues, setPrevMetadataValues] = useState([]);
|
|
35
35
|
const [inputMidsApplied, setInputMidsApplied] = useState(false);
|
|
36
|
-
const onChangeHandler = (newValue, mid) => {
|
|
36
|
+
const onChangeHandler = useCallback((newValue, mid) => {
|
|
37
37
|
let newValues = structuredClone(metadataValues);
|
|
38
38
|
const item = newValues.find(value => value.mid === mid);
|
|
39
39
|
if (item) {
|
|
@@ -51,25 +51,25 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
onValueChanged?.(newValues);
|
|
54
|
-
};
|
|
55
|
-
const editorValidationHandler = (mid) => {
|
|
54
|
+
}, [metadataValues, showCheckBoxes, dynDataListsToBeRefreshed, onValueChanged]);
|
|
55
|
+
const editorValidationHandler = useCallback((mid) => {
|
|
56
56
|
const md = metadataValues?.find(m => m.mid === mid);
|
|
57
57
|
const validationItem = validationItems.find(vil => vil.PropertyName === md?.md?.nameLoc);
|
|
58
58
|
return validationItem ? [validationItem] : [];
|
|
59
|
-
};
|
|
60
|
-
const isEditable = (mid) => {
|
|
59
|
+
}, [metadataValues, validationItems]);
|
|
60
|
+
const isEditable = useCallback((mid) => {
|
|
61
61
|
let md = currentDTD?.metadata?.find(o => o.id == mid);
|
|
62
62
|
if (!md)
|
|
63
63
|
return false;
|
|
64
64
|
let isList = md.dataDomain == MetadataDataDomains.DataList || md.dataDomain == MetadataDataDomains.DynamicDataList || md.dataDomain == MetadataDataDomains.UserID;
|
|
65
65
|
return isList && isEditableList(mid);
|
|
66
|
-
};
|
|
67
|
-
const handleMetadataValueSelection = (item) => {
|
|
66
|
+
}, [currentDTD, isEditableList]);
|
|
67
|
+
const handleMetadataValueSelection = useCallback((item) => {
|
|
68
68
|
if (selectedItem?.mid !== item.mid) {
|
|
69
69
|
setSelectedItem(item);
|
|
70
70
|
onFocusedItemChanged?.(item);
|
|
71
71
|
}
|
|
72
|
-
};
|
|
72
|
+
}, [selectedItem, onFocusedItemChanged]);
|
|
73
73
|
useEffect(() => {
|
|
74
74
|
if (!TID) {
|
|
75
75
|
setCurrentDTD(undefined);
|
|
@@ -184,7 +184,7 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
184
184
|
}
|
|
185
185
|
return toBeRefreshed;
|
|
186
186
|
};
|
|
187
|
-
const getAdvancedMenuItems = (mvd) => {
|
|
187
|
+
const getAdvancedMenuItems = useCallback((mvd) => {
|
|
188
188
|
let md = mvd.md;
|
|
189
189
|
if (!md)
|
|
190
190
|
return [];
|
|
@@ -241,9 +241,9 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
241
241
|
...customMenuItems
|
|
242
242
|
];
|
|
243
243
|
return menu;
|
|
244
|
-
};
|
|
244
|
+
}, [checkPerms, isExpertMode, customMenuItems, metadataValues, onAdvancedMenuClick, onValueChanged]);
|
|
245
245
|
// Helper function to render a single metadata item
|
|
246
|
-
const renderMetadataItem = (item, isReadOnlyOverride = false) => (_jsxs(StyledRow, { style: { marginTop: item.md?.dataType === MetadataDataTypes.DateTime ? '6px' : '0', gap: '8px' }, onClick: () => { handleMetadataValueSelection(item); }, onFocus: () => { handleMetadataValueSelection(item); }, children: [showCheckBoxes !== ShowCheckBoxesMode.Never &&
|
|
246
|
+
const renderMetadataItem = useCallback((item, isReadOnlyOverride = false) => (_jsxs(StyledRow, { style: { marginTop: item.md?.dataType === MetadataDataTypes.DateTime ? '6px' : '0', gap: '8px' }, onClick: () => { handleMetadataValueSelection(item); }, onFocus: () => { handleMetadataValueSelection(item); }, children: [showCheckBoxes !== ShowCheckBoxesMode.Never &&
|
|
247
247
|
_jsx(TMCheckBox, { elementStyle: { marginTop: item.md?.dataType === MetadataDataTypes.DateTime ? '14px' : '20px' }, value: item.isSelected, disabled: showCheckBoxes === ShowCheckBoxesMode.AlwaysReadOnly, onValueChanged: (newValue) => {
|
|
248
248
|
let newValues = structuredClone(metadataValues);
|
|
249
249
|
const mvd = newValues.find(value => value.mid === item.mid);
|
|
@@ -296,8 +296,8 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
296
296
|
mvd.isSelected = !stringIsNullOrEmpty(mvd.value);
|
|
297
297
|
}
|
|
298
298
|
onValueChanged?.(newValues);
|
|
299
|
-
} }) }), !isReadOnly && _jsx("div", { style: { marginTop: item.md?.dataType === MetadataDataTypes.DateTime ? '12px' : '18px' }, onClick: () => { handleMetadataValueSelection(item); }, children: _jsx(TMDropDownMenu, { backgroundColor: 'white', color: TMColors.button_icon, borderRadius: '3px', content: _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconMenuVertical, {}), showTooltip: false }), disabled: item.isLexProt === 1, items: getAdvancedMenuItems(item) }) })] }, item.mid));
|
|
300
|
-
const layoutWorkItem = () => {
|
|
299
|
+
} }) }), !isReadOnly && _jsx("div", { style: { marginTop: item.md?.dataType === MetadataDataTypes.DateTime ? '12px' : '18px' }, onClick: () => { handleMetadataValueSelection(item); }, children: _jsx(TMDropDownMenu, { backgroundColor: 'white', color: TMColors.button_icon, borderRadius: '3px', content: _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconMenuVertical, {}), showTooltip: false }), disabled: item.isLexProt === 1, items: getAdvancedMenuItems(item) }) })] }, item.mid)), [TID, showCheckBoxes, showNullValueCheckBoxes, isReadOnly, layoutMode, selectedMID, isOpenDistinctValues, openChooserBySingleClick, dynDataListsToBeRefreshed, metadataValues, metadataValuesOrig, validationItems, onValueChanged, handleMetadataValueSelection, getAdvancedMenuItems, onChangeHandler, editorValidationHandler, isEditable]);
|
|
300
|
+
const layoutWorkItem = useMemo(() => {
|
|
301
301
|
const workItemData = [];
|
|
302
302
|
const technicalWorkItemData = [];
|
|
303
303
|
const documentData = [];
|
|
@@ -328,8 +328,8 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
328
328
|
}
|
|
329
329
|
});
|
|
330
330
|
return (_jsxs("div", { style: { width: '100%' }, children: [documentData.length > 0 && _jsx(TMAccordion, { title: SDKUI_Localizator.DocumentData, children: documentData.map(item => renderMetadataItem(item)) }), workItemData.length > 0 && _jsx(TMAccordion, { title: SDKUI_Localizator.WorkItemData, children: workItemData.map(item => renderMetadataItem(item, true)) }), technicalWorkItemData.length > 0 && _jsx(TMAccordion, { title: SDKUI_Localizator.WorkItemTechnicalData, defaultCollapsed: true, children: technicalWorkItemData.map(item => renderMetadataItem(item, true)) })] }));
|
|
331
|
-
};
|
|
332
|
-
const layoutDraft = () => {
|
|
331
|
+
}, [metadataValues, showCheckBoxes, showNullValueCheckBoxes, isReadOnly, dynDataListsToBeRefreshed, validationItems, selectedMID, isOpenDistinctValues, openChooserBySingleClick, metadataValuesOrig]);
|
|
332
|
+
const layoutDraft = useMemo(() => {
|
|
333
333
|
// Definiamo l'ordine desiderato per gli elementi
|
|
334
334
|
const desiredDraftOrder = [
|
|
335
335
|
DraftsMIDs.Name,
|
|
@@ -384,36 +384,73 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
384
384
|
checkOutData.push(tempCICODataMap[id]);
|
|
385
385
|
}
|
|
386
386
|
});
|
|
387
|
-
return (_jsxs("div", { style: { width: '100%' }, children: [draftData.length > 0 && _jsx(TMAccordion, { title: SDKUI_Localizator.Draft, children: draftData.map(item => renderMetadataItem(item)) }), checkOutData.length > 0 && _jsx(TMAccordion, { title: `${SDKUI_Localizator.CheckIn}/${SDKUI_Localizator.CheckOut}`, children: checkOutData.map(item => renderMetadataItem(item, true)) })] }));
|
|
388
|
-
};
|
|
389
|
-
const
|
|
387
|
+
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)) })] }));
|
|
388
|
+
}, [metadataValues, showCheckBoxes, showNullValueCheckBoxes, isReadOnly, dynDataListsToBeRefreshed, validationItems, selectedMID, isOpenDistinctValues, openChooserBySingleClick, metadataValuesOrig]);
|
|
389
|
+
const layoutDsAttachs = useMemo(() => {
|
|
390
|
+
const dsAttachsData = [];
|
|
391
|
+
metadataValues.forEach(item => {
|
|
392
|
+
switch (item.md?.id) {
|
|
393
|
+
// case DSAttachsMIDs.DSID:
|
|
394
|
+
case DSAttachsMIDs.Name:
|
|
395
|
+
case DSAttachsMIDs.Description:
|
|
396
|
+
dsAttachsData.push(item);
|
|
397
|
+
break;
|
|
398
|
+
default:
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
return (_jsx("div", { style: { width: '100%' }, children: dsAttachsData.length > 0 && _jsx(TMAccordion, { title: SDKUI_Localizator.Attachment, children: dsAttachsData.map(item => renderMetadataItem(item, isReadOnly)) }) }));
|
|
403
|
+
}, [metadataValues, showCheckBoxes, showNullValueCheckBoxes, isReadOnly, dynDataListsToBeRefreshed, validationItems, selectedMID, isOpenDistinctValues, openChooserBySingleClick, metadataValuesOrig]);
|
|
404
|
+
const layoutCustom = useMemo(() => {
|
|
390
405
|
if (!layout || !layout.items || layout.items.length === 0) {
|
|
391
406
|
return metadataValues.map((item) => renderMetadataItem(item));
|
|
392
407
|
}
|
|
393
|
-
// Build a map of items by ID for quick lookup
|
|
408
|
+
// Build a map of items by ID for quick lookup (include negative/zero IDs)
|
|
394
409
|
const itemsById = new Map();
|
|
395
410
|
layout.items.forEach(item => {
|
|
396
|
-
if (item.layoutItemID) {
|
|
411
|
+
if (item.layoutItemID !== undefined && item.layoutItemID !== null) {
|
|
397
412
|
itemsById.set(item.layoutItemID, item);
|
|
398
413
|
}
|
|
399
414
|
});
|
|
400
|
-
//
|
|
401
|
-
|
|
402
|
-
|
|
415
|
+
// Determine root items. Prefer explicit LayoutRoot items if present;
|
|
416
|
+
// otherwise fall back to items with no parent (parentID undefined or -1).
|
|
417
|
+
const hasExplicitRoot = layout.items.some(item => item.type === LayoutItemTypes.LayoutRoot);
|
|
418
|
+
const rootItems = hasExplicitRoot
|
|
419
|
+
? layout.items.filter(item => item.type === LayoutItemTypes.LayoutRoot)
|
|
420
|
+
: layout.items.filter(item => item.parentID === undefined || item.parentID === -1);
|
|
421
|
+
// Recursive function to get children of an item. Handle parentID === -1 and undefined
|
|
422
|
+
// because some layouts use -1 for root while children use undefined.
|
|
403
423
|
const getChildren = (parentID) => {
|
|
424
|
+
if (parentID === -1) {
|
|
425
|
+
return layout.items?.filter(item => item.parentID === -1 || item.parentID === undefined) || [];
|
|
426
|
+
}
|
|
427
|
+
if (parentID === undefined) {
|
|
428
|
+
return layout.items?.filter(item => item.parentID === undefined) || [];
|
|
429
|
+
}
|
|
404
430
|
return layout.items?.filter(item => item.parentID === parentID) || [];
|
|
405
431
|
};
|
|
406
432
|
// Recursive function to render layout items with depth tracking for indentation
|
|
407
|
-
|
|
433
|
+
// Prevent infinite recursion by tracking visited layoutItemIDs (handles malformed layouts where an item
|
|
434
|
+
// may reference itself as a child or cycles exist).
|
|
435
|
+
const renderLayoutItem = (layoutItem, depth = 0, visited = new Set()) => {
|
|
436
|
+
const id = layoutItem.layoutItemID ?? 0;
|
|
437
|
+
if (visited.has(id))
|
|
438
|
+
return null;
|
|
439
|
+
visited.add(id);
|
|
440
|
+
// Check if this is a LayoutRoot - just render its children
|
|
441
|
+
if (layoutItem.type === LayoutItemTypes.LayoutRoot) {
|
|
442
|
+
const children = getChildren(layoutItem.layoutItemID);
|
|
443
|
+
return (_jsx(React.Fragment, { children: children.map(child => renderLayoutItem(child, depth, visited)) }, `root-${layoutItem.layoutItemID}`));
|
|
444
|
+
}
|
|
408
445
|
// Check if this is a LayoutGroup
|
|
409
|
-
if (layoutItem.type === LayoutItemTypes.LayoutGroup && layoutItem.lgd) {
|
|
410
|
-
const children = getChildren(layoutItem.layoutItemID
|
|
446
|
+
else if (layoutItem.type === LayoutItemTypes.LayoutGroup && layoutItem.lgd) {
|
|
447
|
+
const children = getChildren(layoutItem.layoutItemID);
|
|
411
448
|
const groupDescriptor = layoutItem.lgd;
|
|
412
449
|
const groupTitle = groupDescriptor.caption || `Group ${layoutItem.layoutItemID}`;
|
|
413
450
|
const isCollapsed = false; // LayoutGroupDescriptor doesn't have collapsed property
|
|
414
451
|
// Apply indentation only to subgroups (depth > 0), not to root groups
|
|
415
452
|
const indentationPx = depth > 0 ? depth * 10 : 0;
|
|
416
|
-
return (_jsx("div", { style: { paddingLeft: `${indentationPx}px` }, children: _jsx(TMAccordion, { title: groupTitle, defaultCollapsed: isCollapsed, children: children.map(child => renderLayoutItem(child, depth + 1)) }) }, `group-wrapper-${layoutItem.layoutItemID}`));
|
|
453
|
+
return (_jsx("div", { style: { paddingLeft: `${indentationPx}px` }, children: _jsx(TMAccordion, { title: groupTitle, defaultCollapsed: isCollapsed, children: children.map(child => renderLayoutItem(child, depth + 1, visited)) }) }, `group-wrapper-${layoutItem.layoutItemID}`));
|
|
417
454
|
}
|
|
418
455
|
// Check if this is a LayoutControlItem (metadata field)
|
|
419
456
|
else if (layoutItem.type === LayoutItemTypes.LayoutControlItem && layoutItem.lcid) {
|
|
@@ -425,8 +462,9 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
425
462
|
const metadataItem = metadataValues.find(m => m.mid === mid);
|
|
426
463
|
if (!metadataItem)
|
|
427
464
|
return null;
|
|
428
|
-
//
|
|
429
|
-
|
|
465
|
+
// Indent control items based on depth so they align under groups
|
|
466
|
+
const controlIndentPx = depth > 0 ? depth * 10 : 15;
|
|
467
|
+
return (_jsx("div", { style: { paddingLeft: `${controlIndentPx}px` }, children: renderMetadataItem(metadataItem) }, `control-${layoutItem.layoutItemID}`));
|
|
430
468
|
}
|
|
431
469
|
// Check if this is a SeparatorItem (horizontal line)
|
|
432
470
|
else if (layoutItem.type === LayoutItemTypes.SeparatorItem) {
|
|
@@ -434,27 +472,39 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
434
472
|
}
|
|
435
473
|
return null;
|
|
436
474
|
};
|
|
437
|
-
return (_jsx("div", { style: { width: '100%' }, children:
|
|
438
|
-
|
|
439
|
-
|
|
475
|
+
return (_jsx("div", { style: { width: '100%' }, children: (() => {
|
|
476
|
+
const visited = new Set();
|
|
477
|
+
return rootItems.map(item => renderLayoutItem(item, 0, visited));
|
|
478
|
+
})() }));
|
|
479
|
+
}, [layout, metadataValues, showCheckBoxes, showNullValueCheckBoxes, isReadOnly, dynDataListsToBeRefreshed, validationItems, selectedMID, isOpenDistinctValues, openChooserBySingleClick, metadataValuesOrig]);
|
|
480
|
+
const renderForm = useMemo(() => {
|
|
481
|
+
// Se currentDTD non è ancora stato caricato, non renderizzare nulla
|
|
482
|
+
if (!currentDTD) {
|
|
483
|
+
return null;
|
|
484
|
+
}
|
|
485
|
+
// Se tutti i metadata sono di sistema, renderizziamo tutti in sola lettura senza layout
|
|
486
|
+
const allSystem = metadataValues.length > 0 && metadataValues.every(item => item.md?.isSystem === 1);
|
|
487
|
+
if (allSystem) {
|
|
488
|
+
return metadataValues.map((item) => renderMetadataItem(item, true));
|
|
489
|
+
}
|
|
440
490
|
if (currentDTD?.templateTID === TemplateTIDs.WF_WIApprView && !isReadOnly) {
|
|
441
|
-
return layoutWorkItem
|
|
491
|
+
return layoutWorkItem;
|
|
442
492
|
}
|
|
443
493
|
switch (currentDTD?.id) {
|
|
444
|
-
case SystemTIDs.Drafts: return
|
|
494
|
+
case SystemTIDs.Drafts: return layoutDraft;
|
|
445
495
|
// case SystemTIDs.Chronology: break;
|
|
446
|
-
|
|
496
|
+
case SystemTIDs.DSAttachs: return layoutDsAttachs;
|
|
447
497
|
default:
|
|
448
498
|
// Se è presente un layout personalizzato, usalo, altrimenti usa il rendering standard
|
|
449
499
|
if (layout && layout.items && layout.items.length > 0) {
|
|
450
|
-
return layoutCustom
|
|
500
|
+
return layoutCustom;
|
|
451
501
|
}
|
|
452
502
|
return metadataValues.map((item) => renderMetadataItem(item));
|
|
453
503
|
}
|
|
454
|
-
};
|
|
504
|
+
}, [currentDTD, metadataValues, layout, isReadOnly, showCheckBoxes, showNullValueCheckBoxes, dynDataListsToBeRefreshed, validationItems, selectedMID, isOpenDistinctValues, openChooserBySingleClick, metadataValuesOrig]);
|
|
455
505
|
return (_jsx(StyledMetadataValuesContainer, { children: !TID ?
|
|
456
506
|
_jsx(TMNothingToShow, { text: `${SDKUI_Localizator.NoDcmtSelected}.`, secondText: `${SDKUI_Localizator.MetadataSystem} - ${SDKUI_Localizator.NotAvailable}`, icon: _jsx(IconDcmtTypeSys, { fontSize: 96 }) }) :
|
|
457
|
-
_jsx(_Fragment, { children: renderForm
|
|
507
|
+
_jsx(_Fragment, { children: renderForm }) }));
|
|
458
508
|
};
|
|
459
509
|
export default TMMetadataValues;
|
|
460
510
|
//#region Styled Components
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
|
|
2
3
|
interface ITMArchiveProps {
|
|
3
4
|
inputFile?: File | null;
|
|
4
5
|
inputMids?: Array<{
|
|
@@ -6,6 +7,7 @@ interface ITMArchiveProps {
|
|
|
6
7
|
value: string;
|
|
7
8
|
}>;
|
|
8
9
|
inputTID?: number;
|
|
10
|
+
inputDID?: number;
|
|
9
11
|
onDcmtTypeSelect?: (tid: number | undefined) => void;
|
|
10
12
|
connectorFileSave?: () => Promise<File>;
|
|
11
13
|
onSavedAsyncCallback?: (tid: number | undefined, did: number | undefined) => Promise<void>;
|
|
@@ -14,6 +16,14 @@ interface ITMArchiveProps {
|
|
|
14
16
|
mid: number;
|
|
15
17
|
value: string;
|
|
16
18
|
}>) => void;
|
|
19
|
+
isSharedArchive?: boolean;
|
|
20
|
+
allTasks?: Array<TaskDescriptor>;
|
|
21
|
+
getAllTasks?: () => Promise<void>;
|
|
22
|
+
deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
|
|
23
|
+
addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
|
|
24
|
+
editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
|
|
25
|
+
handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
|
|
26
|
+
handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
|
|
17
27
|
}
|
|
18
28
|
declare const TMArchive: React.FunctionComponent<ITMArchiveProps>;
|
|
19
29
|
export default TMArchive;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import Logo from '../../../assets/Toppy-generico.png';
|
|
4
4
|
import { DcmtTypeListCacheService, LayoutModes, SDK_Localizator } from '@topconsultnpm/sdk-ts';
|
|
5
5
|
import { IconTree, SDKUI_Globals, SDKUI_Localizator, IconRecentlyViewed, IconPreview, IconShow, IconBoard, IconDcmtTypeSys, removeMruTid } from '../../../helper';
|
|
@@ -12,11 +12,14 @@ import TMTreeSelector from '../search/TMTreeSelector';
|
|
|
12
12
|
import TMPanel from '../../base/TMPanel';
|
|
13
13
|
import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/panelManager/TMPanelManagerContext';
|
|
14
14
|
import TMPanelManagerContainer from '../../layout/panelManager/TMPanelManagerContainer';
|
|
15
|
-
const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, connectorFileSave = undefined, onSavedAsyncCallback, inputMids = [], enableDragDropOverlay = false, passToSearch }) => {
|
|
15
|
+
const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, connectorFileSave = undefined, onSavedAsyncCallback, inputMids = [], enableDragDropOverlay = false, passToSearch, isSharedArchive = false, inputDID = undefined, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
|
|
16
16
|
const [currentTID, setCurrentTID] = useState(inputTID ?? 0);
|
|
17
17
|
const [mruTIDs, setMruTIDs] = useState([]);
|
|
18
18
|
const [currentMruTID, setCurrentMruTID] = useState(0);
|
|
19
19
|
const [fromDTD, setFromDTD] = useState();
|
|
20
|
+
const [currentInputMids, setCurrentInputMids] = useState(inputMids);
|
|
21
|
+
const previousTIDRef = React.useRef(undefined);
|
|
22
|
+
const pendingMidsRef = React.useRef(null);
|
|
20
23
|
const deviceType = useDeviceType();
|
|
21
24
|
useEffect(() => { setMruTIDs(SDKUI_Globals.userSettings.archivingSettings.mruTIDs); }, []);
|
|
22
25
|
useEffect(() => {
|
|
@@ -24,9 +27,16 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
|
|
|
24
27
|
return;
|
|
25
28
|
setCurrentTID(inputTID);
|
|
26
29
|
setCurrentMruTID(mruTIDs.includes(inputTID) ? inputTID : 0);
|
|
27
|
-
}, [inputTID]);
|
|
30
|
+
}, [inputTID, mruTIDs]);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
pendingMidsRef.current = inputMids;
|
|
33
|
+
if (currentTID && currentTID > 0 && inputMids && inputMids.length > 0) {
|
|
34
|
+
setCurrentInputMids(inputMids);
|
|
35
|
+
}
|
|
36
|
+
}, [inputMids, currentTID]);
|
|
28
37
|
useEffect(() => {
|
|
29
38
|
if (!currentTID || currentTID <= 0) {
|
|
39
|
+
previousTIDRef.current = currentTID;
|
|
30
40
|
return;
|
|
31
41
|
}
|
|
32
42
|
if (onDcmtTypeSelect)
|
|
@@ -34,31 +44,42 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
|
|
|
34
44
|
DcmtTypeListCacheService.GetAsync(currentTID).then(async (dtd) => {
|
|
35
45
|
setFromDTD(dtd);
|
|
36
46
|
});
|
|
37
|
-
|
|
47
|
+
if (previousTIDRef.current !== undefined && previousTIDRef.current > 0 && previousTIDRef.current !== currentTID) {
|
|
48
|
+
if (!isSharedArchive) {
|
|
49
|
+
setCurrentInputMids([]);
|
|
50
|
+
}
|
|
51
|
+
if (pendingMidsRef.current && pendingMidsRef.current.length > 0) {
|
|
52
|
+
setCurrentInputMids(pendingMidsRef.current);
|
|
53
|
+
pendingMidsRef.current = null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
previousTIDRef.current = currentTID;
|
|
57
|
+
}, [currentTID, onDcmtTypeSelect, isSharedArchive]);
|
|
38
58
|
const isMobile = deviceType === DeviceType.MOBILE;
|
|
39
|
-
const tmTreeSelectorElement = useMemo(() => _jsx(TMTreeSelectorWrapper, { isMobile: isMobile, onSelectedTIDChanged: (tid) => {
|
|
59
|
+
const tmTreeSelectorElement = useMemo(() => _jsx(TMTreeSelectorWrapper, { isMobile: isMobile, isSharedArchive: isSharedArchive, onSelectedTIDChanged: (tid) => {
|
|
40
60
|
setCurrentTID(tid);
|
|
41
61
|
if (tid && mruTIDs.includes(tid))
|
|
42
62
|
setCurrentMruTID(tid);
|
|
43
63
|
else
|
|
44
64
|
setCurrentMruTID(0);
|
|
45
|
-
} }), [isMobile, currentTID]);
|
|
46
|
-
const tmRecentsManagerElement = useMemo(() => _jsx(TMRecentsManagerWrapper, { mruTIDs: mruTIDs, currentTID: currentTID, currentMruTID: currentMruTID, deviceType: deviceType, onSelectedTID: (tid) => {
|
|
65
|
+
} }), [isMobile, currentTID, isSharedArchive]);
|
|
66
|
+
const tmRecentsManagerElement = useMemo(() => _jsx(TMRecentsManagerWrapper, { mruTIDs: mruTIDs, currentTID: currentTID, currentMruTID: currentMruTID, deviceType: deviceType, isSharedArchive: isSharedArchive, onSelectedTID: (tid) => {
|
|
47
67
|
setCurrentMruTID(tid);
|
|
48
68
|
setCurrentTID(tid);
|
|
49
69
|
}, onDeletedTID: (tid) => {
|
|
50
70
|
let newMruTIDS = removeMruTid(SDKUI_Globals.userSettings.archivingSettings.mruTIDs, tid);
|
|
51
71
|
SDKUI_Globals.userSettings.archivingSettings.mruTIDs = newMruTIDS;
|
|
52
72
|
setMruTIDs(newMruTIDS);
|
|
53
|
-
} }), [mruTIDs, currentMruTID, deviceType]);
|
|
73
|
+
} }), [mruTIDs, currentMruTID, deviceType, isSharedArchive]);
|
|
54
74
|
const tmFormElement = useMemo(() => currentTID ?
|
|
55
|
-
_jsx(TMDcmtForm, { TID: currentTID, DID: undefined, groupId: 'tmForm', layoutMode: LayoutModes.Ark, onClose: deviceType === DeviceType.MOBILE ? () => setCurrentTID(undefined) : undefined, onSaveRecents: (TIDs) => setMruTIDs(TIDs), showDcmtFormSidebar: false, inputFile: inputFile, connectorFileSave: connectorFileSave, onSavedAsyncCallback: onSavedAsyncCallback, inputMids:
|
|
75
|
+
_jsx(TMDcmtForm, { TID: currentTID, DID: currentTID === inputTID ? inputDID : undefined, sharedSourceTID: isSharedArchive ? inputTID : undefined, sharedSourceDID: isSharedArchive ? inputDID : undefined, groupId: 'tmForm', layoutMode: LayoutModes.Ark, onClose: deviceType === DeviceType.MOBILE ? () => setCurrentTID(undefined) : undefined, onSaveRecents: (TIDs) => setMruTIDs(TIDs), showDcmtFormSidebar: false, inputFile: inputFile, connectorFileSave: connectorFileSave, onSavedAsyncCallback: onSavedAsyncCallback, inputMids: currentInputMids, enableDragDropOverlay: enableDragDropOverlay, passToSearch: passToSearch ? (outputMids, tid) => {
|
|
76
|
+
const tidToUse = tid ?? currentTID;
|
|
56
77
|
if (onDcmtTypeSelect)
|
|
57
|
-
onDcmtTypeSelect(
|
|
58
|
-
passToSearch(
|
|
59
|
-
} : undefined })
|
|
78
|
+
onDcmtTypeSelect(tidToUse);
|
|
79
|
+
passToSearch(tidToUse, outputMids);
|
|
80
|
+
} : undefined, isSharedDcmt: isSharedArchive, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }, currentTID)
|
|
60
81
|
:
|
|
61
|
-
_jsx(TMPanel, { title: 'Archiviazione', allowMaximize: false, children: _jsxs(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: [_jsx(StyledToppyTextContainer, { children: _jsx(StyledToppyText, { children: SDKUI_Localizator.DcmtTypeSelect }) }), _jsx(StyledToppyImage, { src: Logo, alt: 'Toppy' })] }) }), [currentTID, deviceType, mruTIDs, inputFile,
|
|
82
|
+
_jsx(TMPanel, { title: 'Archiviazione', allowMaximize: false, children: _jsxs(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: [_jsx(StyledToppyTextContainer, { children: _jsx(StyledToppyText, { children: SDKUI_Localizator.DcmtTypeSelect }) }), _jsx(StyledToppyImage, { src: Logo, alt: 'Toppy' })] }) }), [currentTID, deviceType, mruTIDs, inputFile, currentInputMids, enableDragDropOverlay, isSharedArchive, allTasks]);
|
|
62
83
|
const allInitialPanelVisibility = {
|
|
63
84
|
'tmTreeSelector': true,
|
|
64
85
|
'tmRecentsManager': true,
|
|
@@ -66,13 +87,13 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
|
|
|
66
87
|
'tmDcmtForm': true,
|
|
67
88
|
'tmBlog': false,
|
|
68
89
|
'tmSysMetadata': false,
|
|
69
|
-
'tmDcmtPreview':
|
|
90
|
+
'tmDcmtPreview': !isSharedArchive,
|
|
70
91
|
};
|
|
71
92
|
const initialPanelDimensions = {
|
|
72
93
|
'tmTreeSelector': { width: '20%', height: '100%' },
|
|
73
94
|
'tmRecentsManager': { width: '20%', height: '100%' },
|
|
74
95
|
'tmForm': { width: '60%', height: '100%' },
|
|
75
|
-
'tmDcmtForm': { width: '25%', height: '100%' },
|
|
96
|
+
'tmDcmtForm': { width: isSharedArchive ? '50%' : '25%', height: '100%' },
|
|
76
97
|
'tmBlog': { width: '25%', height: '100%' },
|
|
77
98
|
'tmSysMetadata': { width: '25%', height: '100%' },
|
|
78
99
|
'tmDcmtPreview': { width: '25%', height: '100%' },
|
|
@@ -114,15 +135,15 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
|
|
|
114
135
|
{
|
|
115
136
|
id: 'tmDcmtPreview',
|
|
116
137
|
name: SDKUI_Localizator.PreviewDocument,
|
|
117
|
-
toolbarOptions: { icon: _jsx(IconShow, { fontSize: 24 }), visible: false, orderNumber: 7, isActive: allInitialPanelVisibility['tmDcmtPreview'] }
|
|
138
|
+
toolbarOptions: { icon: _jsx(IconShow, { fontSize: 24 }), visible: false, disabled: isSharedArchive, orderNumber: 7, isActive: allInitialPanelVisibility['tmDcmtPreview'] }
|
|
118
139
|
}
|
|
119
140
|
]
|
|
120
141
|
},
|
|
121
|
-
], [tmTreeSelectorElement, tmRecentsManagerElement, tmFormElement, currentTID, mruTIDs]);
|
|
142
|
+
], [tmTreeSelectorElement, tmRecentsManagerElement, tmFormElement, currentTID, mruTIDs, isSharedArchive]);
|
|
122
143
|
return (_jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmRecentsManager', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }));
|
|
123
144
|
};
|
|
124
145
|
export default TMArchive;
|
|
125
|
-
const TMTreeSelectorWrapper = ({ isMobile, onSelectedTIDChanged }) => {
|
|
146
|
+
const TMTreeSelectorWrapper = ({ isMobile, isSharedArchive, onSelectedTIDChanged }) => {
|
|
126
147
|
const { setPanelVisibilityById, toggleMaximize, setToolbarButtonVisibility, countVisibleLeafPanels } = useTMPanelManagerContext();
|
|
127
148
|
return (_jsx(TMTreeSelector, { layoutMode: LayoutModes.Ark, onClosePanel: !isMobile && countVisibleLeafPanels() > 1 ? () => setPanelVisibilityById('tmTreeSelector', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: !isMobile && countVisibleLeafPanels() > 1 ? () => toggleMaximize("tmTreeSelector") : undefined, onSelectedTIDChanged: (tid) => {
|
|
128
149
|
onSelectedTIDChanged?.(tid);
|
|
@@ -130,21 +151,27 @@ const TMTreeSelectorWrapper = ({ isMobile, onSelectedTIDChanged }) => {
|
|
|
130
151
|
setPanelVisibilityById('tmDcmtForm', true);
|
|
131
152
|
else {
|
|
132
153
|
setPanelVisibilityById('tmDcmtForm', true);
|
|
133
|
-
|
|
154
|
+
if (!isSharedArchive) {
|
|
155
|
+
setPanelVisibilityById('tmDcmtPreview', true);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (!isSharedArchive) {
|
|
159
|
+
setToolbarButtonVisibility('tmDcmtPreview', true);
|
|
134
160
|
}
|
|
135
|
-
setToolbarButtonVisibility('tmDcmtPreview', true);
|
|
136
161
|
setToolbarButtonVisibility('tmDcmtForm', true);
|
|
137
162
|
} }));
|
|
138
163
|
};
|
|
139
|
-
const TMRecentsManagerWrapper = ({ mruTIDs, currentTID, currentMruTID, deviceType, onSelectedTID, onDeletedTID }) => {
|
|
164
|
+
const TMRecentsManagerWrapper = ({ mruTIDs, currentTID, currentMruTID, deviceType, isSharedArchive, onSelectedTID, onDeletedTID }) => {
|
|
140
165
|
const { setPanelVisibilityById, setToolbarButtonVisibility } = useTMPanelManagerContext();
|
|
141
166
|
useEffect(() => {
|
|
142
167
|
if (currentTID) {
|
|
143
168
|
setPanelVisibilityById('tmDcmtForm', true);
|
|
144
|
-
|
|
169
|
+
if (!isSharedArchive) {
|
|
170
|
+
setToolbarButtonVisibility('tmDcmtPreview', true);
|
|
171
|
+
}
|
|
145
172
|
setToolbarButtonVisibility('tmDcmtForm', true);
|
|
146
173
|
}
|
|
147
|
-
}, [currentTID]);
|
|
174
|
+
}, [currentTID, isSharedArchive]);
|
|
148
175
|
return (_jsx(TMRecentsManager, { accessFilter: 'canArchive', mruTIDs: mruTIDs, currentMruTID: currentMruTID, deviceType: deviceType, onSelectedTID: (tid) => {
|
|
149
176
|
onSelectedTID?.(tid);
|
|
150
177
|
if (deviceType === DeviceType.MOBILE) {
|
|
@@ -152,9 +179,13 @@ const TMRecentsManagerWrapper = ({ mruTIDs, currentTID, currentMruTID, deviceTyp
|
|
|
152
179
|
}
|
|
153
180
|
else {
|
|
154
181
|
setPanelVisibilityById('tmDcmtForm', true);
|
|
155
|
-
|
|
182
|
+
if (!isSharedArchive) {
|
|
183
|
+
setPanelVisibilityById('tmDcmtPreview', true);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (!isSharedArchive) {
|
|
187
|
+
setToolbarButtonVisibility('tmDcmtPreview', true);
|
|
156
188
|
}
|
|
157
|
-
setToolbarButtonVisibility('tmDcmtPreview', true);
|
|
158
189
|
setToolbarButtonVisibility('tmDcmtForm', true);
|
|
159
190
|
}, onDeletedTID: (tid) => {
|
|
160
191
|
onDeletedTID?.(tid);
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { UserDescriptor } from "@topconsultnpm/sdk-ts";
|
|
2
|
-
import { TMBlogContextDescriptor } from '../../grids/TMBlogsUtils';
|
|
1
|
+
import { BlogPost, UserDescriptor } from "@topconsultnpm/sdk-ts";
|
|
3
2
|
import { FileItem } from '../../base/TMFileManagerUtils';
|
|
3
|
+
import { TMBlogContextDescriptor } from '../../grids/TMBlogsPostUtils';
|
|
4
4
|
interface TMBlogCommentFormProps {
|
|
5
5
|
context: TMBlogContextDescriptor;
|
|
6
6
|
participants: Array<UserDescriptor>;
|
|
7
7
|
onClose: () => void;
|
|
8
|
-
refreshCallback: () => Promise<void>;
|
|
9
8
|
showAttachmentsSection?: boolean;
|
|
10
9
|
selectedAttachments?: Array<FileItem>;
|
|
11
10
|
selectedAttachmentDid?: Array<number>;
|
|
12
11
|
allFileItems?: FileItem;
|
|
13
12
|
allArchivedDocumentsFileItems?: Array<FileItem>;
|
|
14
|
-
|
|
13
|
+
onFilterCreated?: (predicate: (post: BlogPost) => boolean) => void;
|
|
14
|
+
refreshCallback?: () => Promise<void>;
|
|
15
15
|
}
|
|
16
16
|
declare const TMBlogCommentForm: (props: TMBlogCommentFormProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
17
|
export default TMBlogCommentForm;
|