@topconsultnpm/sdkui-react 6.19.0-dev1.5 → 6.19.0-dev1.51
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/Styled.d.ts +1 -0
- package/lib/components/base/Styled.js +40 -0
- package/lib/components/base/TMFileManagerDataGridView.js +4 -1
- 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 +2 -0
- package/lib/components/features/archive/TMArchive.js +56 -25
- package/lib/components/features/blog/TMBlogCommentForm.js +57 -41
- package/lib/components/features/documents/TMDcmtForm.d.ts +10 -3
- package/lib/components/features/documents/TMDcmtForm.js +138 -36
- package/lib/components/features/documents/TMDragDropOverlay.js +2 -1
- package/lib/components/features/documents/TMMasterDetailDcmts.js +1 -1
- 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 +3 -1
- package/lib/components/features/search/TMSearch.js +13 -4
- 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 +3 -1
- package/lib/components/features/search/TMSearchResult.js +102 -328
- package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +2 -2
- package/lib/components/features/search/TMSearchResultsMenuItems.js +32 -15
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +3 -1
- package/lib/components/features/workflow/TMWorkflowPopup.js +17 -4
- package/lib/components/forms/TMChooserForm.d.ts +1 -1
- package/lib/components/forms/TMChooserForm.js +2 -2
- package/lib/components/grids/TMBlogsUtils.d.ts +1 -0
- package/lib/components/grids/TMBlogsUtils.js +40 -4
- package/lib/components/index.d.ts +3 -0
- package/lib/components/index.js +3 -0
- package/lib/components/viewers/TMTidViewer.js +29 -4
- package/lib/css/tm-sdkui.css +1 -1
- package/lib/helper/SDKUI_Globals.d.ts +2 -1
- package/lib/helper/SDKUI_Globals.js +1 -0
- package/lib/helper/SDKUI_Localizator.d.ts +4 -0
- package/lib/helper/SDKUI_Localizator.js +46 -0
- package/lib/helper/TMIcons.d.ts +2 -0
- package/lib/helper/TMIcons.js +6 -0
- package/lib/helper/TMToppyMessage.d.ts +7 -0
- package/lib/helper/TMToppyMessage.js +42 -0
- package/lib/helper/TMUtils.d.ts +7 -0
- package/lib/helper/TMUtils.js +16 -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 +2 -2
|
@@ -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 }) => {
|
|
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 }, 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]);
|
|
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);
|
|
@@ -10,7 +10,7 @@ import { TMExceptionBoxManager, TMMessageBoxManager, ButtonNames } from '../../b
|
|
|
10
10
|
import TMSpinner from '../../base/TMSpinner';
|
|
11
11
|
import TMTooltip from '../../base/TMTooltip';
|
|
12
12
|
import TMUserAvatar from '../../base/TMUserAvatar';
|
|
13
|
-
import TMHtmlEditor from '../../editors/TMHtmlEditor';
|
|
13
|
+
import TMHtmlEditor, { sanitizeAndFormatComment } from '../../editors/TMHtmlEditor';
|
|
14
14
|
import TMChooserForm from '../../forms/TMChooserForm';
|
|
15
15
|
import TMSaveForm from '../../forms/TMSaveForm';
|
|
16
16
|
const getNonDirectoryFiles = (items, exclude) => {
|
|
@@ -28,6 +28,7 @@ const getNonDirectoryFiles = (items, exclude) => {
|
|
|
28
28
|
});
|
|
29
29
|
};
|
|
30
30
|
const TMBlogCommentForm = (props) => {
|
|
31
|
+
const maxLength = 1000;
|
|
31
32
|
const { participants, selectedAttachments, selectedAttachmentDid, allFileItems, allArchivedDocumentsFileItems = [], onClose, refreshCallback, context, showAttachmentsSection = true, updateShouldSelectLastBlog } = props;
|
|
32
33
|
// Initialize state with combined array
|
|
33
34
|
const [dataSource, setDataSource] = useState(() => [...getNonDirectoryFiles(allFileItems?.items || [], []), ...allArchivedDocumentsFileItems]);
|
|
@@ -39,14 +40,18 @@ const TMBlogCommentForm = (props) => {
|
|
|
39
40
|
const validator = async (params) => {
|
|
40
41
|
let vil = [];
|
|
41
42
|
const { comment } = params;
|
|
43
|
+
const cleanedMarkup = sanitizeAndFormatComment(comment);
|
|
42
44
|
// Check for empty comment
|
|
43
|
-
if (!
|
|
45
|
+
if (!cleanedMarkup || cleanedMarkup.trim() === "") {
|
|
44
46
|
vil.push(new ValidationItem(ResultTypes.ERROR, SDKUI_Localizator.Comment, `${SDK_Localizator.RequiredField}`));
|
|
45
47
|
}
|
|
46
48
|
else {
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
// Calcola la lunghezza effettiva del commento inserito
|
|
50
|
+
const commentLength = cleanedMarkup.length;
|
|
51
|
+
const exceededChars = commentLength - maxLength;
|
|
52
|
+
// Validate description length (max 1000)
|
|
53
|
+
if (commentLength > maxLength) {
|
|
54
|
+
vil.push(new ValidationItem(ResultTypes.ERROR, SDKUI_Localizator.Comment, `${SDKUI_Localizator.DescriptionLengthExceededMessage.replaceParams(exceededChars)}`));
|
|
50
55
|
}
|
|
51
56
|
// Detect dangerous HTML tags
|
|
52
57
|
const tagRegex = /<\/?(script|iframe|embed|object|link|style|img|video|audio|svg|form|input|button|textarea|select|pre|function)[^>]*>/gi;
|
|
@@ -108,20 +113,8 @@ const TMBlogCommentForm = (props) => {
|
|
|
108
113
|
const blogPost = new BlogPost();
|
|
109
114
|
// Retrieve the comment from formData, or use an empty string if undefined
|
|
110
115
|
const comment = formData?.comment ?? "";
|
|
111
|
-
// Clean the comment
|
|
112
|
-
|
|
113
|
-
// Replace </p> with '' only if followed by <ol> or <ul>
|
|
114
|
-
.replace(/<\/p>(?=\s*<(ol|ul)>)/gi, '')
|
|
115
|
-
// Replace all other </p> with '\r\n'
|
|
116
|
-
.replace(/<\/p>/gi, '\r\n')
|
|
117
|
-
// Remove all <p> tags
|
|
118
|
-
.replace(/<p>/gi, '')
|
|
119
|
-
// Remove all <br> tags
|
|
120
|
-
.replace(/<br>/gi, '')
|
|
121
|
-
// Trim whitespace
|
|
122
|
-
.trim();
|
|
123
|
-
// Validate and remove any potentially dangerous HTML tags (like <script>, <iframe>, etc.)
|
|
124
|
-
cleanComment = cleanComment.replace(/<(script|iframe|embed|object|link|style|img|video|audio|svg|form|input|button|textarea|select|pre|function)[^>]*>/gi, '');
|
|
116
|
+
// Clean the comment using the sanitizeAndFormatComment function
|
|
117
|
+
const cleanComment = sanitizeAndFormatComment(comment);
|
|
125
118
|
// Assign the cleaned comment as the description for the blog post
|
|
126
119
|
blogPost.description = cleanComment ?? "";
|
|
127
120
|
// If there are file items (attachments), process them
|
|
@@ -214,7 +207,7 @@ const TMBlogCommentForm = (props) => {
|
|
|
214
207
|
// Update the state with selected draft items
|
|
215
208
|
setCurrentDraftAttachments(selectedDraftItems);
|
|
216
209
|
};
|
|
217
|
-
return _jsx(TMSaveForm, { id: 1, title: SDKUI_Localizator.AddNewComment, showTitleFormMode: false, showErrorCount: false, customSaveButton: _jsx("i", { className: 'dx-icon-send' }), customTooltipSaveButton: SDKUI_Localizator.Send, showUndoButton: false, hasNavigation: false, skipIsModifiedCheck: true, isModal: true, width: calcResponsiveSizes(deviceType, '800px', '800px', '95%'), height: '550px', formMode: FormModes.Create, validationItems: validationItems, exception: exception, isModified: calcIsModified(formData, formDataOrig), onSaveAsync: onSaveAsync, onClose: onCloseCallback, customToolbarElements: _jsx("div", { style: { display: 'flex', gap: '2px' }, children: _jsx(TMButton, { btnStyle: "toolbar", icon: isEditorEnabled ? _jsx("i", { className: 'dx-icon-font' }) : _jsx("i", { className: 'dx-icon-background' }), caption: isEditorEnabled ? SDKUI_Localizator.HideFormattingOptions : SDKUI_Localizator.ShowFormattingOptions, onClick: toggleEditorMode }) }), children: _jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx("div", { style: { width: "100%", height: showAttachmentsSection ? "calc(100% - 60px)" : "100%" }, children: _jsx(TMHtmlEditor, { width: '100%', height: '100%', isEditorEnabled: isEditorEnabled, validationItems: validationItems, onValueChanged: onValueChanged, mentionsConfig: mentionsConfig, autoFocus: true }) }), showAttachmentsSection && _jsxs("div", { style: { display: 'flex', alignItems: 'center', height: '60px', marginTop: '10px' }, children: [_jsx("div", { style: {
|
|
210
|
+
return _jsx(TMSaveForm, { id: 1, title: SDKUI_Localizator.AddNewComment, showTitleFormMode: false, showErrorCount: false, customSaveButton: _jsx("i", { className: 'dx-icon-send' }), customTooltipSaveButton: SDKUI_Localizator.Send, showUndoButton: false, hasNavigation: false, skipIsModifiedCheck: true, isModal: true, width: calcResponsiveSizes(deviceType, '800px', '800px', '95%'), height: '550px', formMode: FormModes.Create, validationItems: validationItems, exception: exception, isModified: calcIsModified(formData, formDataOrig), onSaveAsync: onSaveAsync, onClose: onCloseCallback, customToolbarElements: _jsx("div", { style: { display: 'flex', gap: '2px' }, children: _jsx(TMButton, { btnStyle: "toolbar", icon: isEditorEnabled ? _jsx("i", { className: 'dx-icon-font' }) : _jsx("i", { className: 'dx-icon-background' }), caption: isEditorEnabled ? SDKUI_Localizator.HideFormattingOptions : SDKUI_Localizator.ShowFormattingOptions, onClick: toggleEditorMode }) }), children: _jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx("div", { style: { width: "100%", height: showAttachmentsSection ? "calc(100% - 60px)" : "100%" }, children: _jsx(TMHtmlEditor, { width: '100%', height: '100%', isEditorEnabled: isEditorEnabled, validationItems: validationItems, onValueChanged: onValueChanged, mentionsConfig: mentionsConfig, autoFocus: true, maxLength: maxLength }) }), showAttachmentsSection && _jsxs("div", { style: { display: 'flex', alignItems: 'center', height: '60px', marginTop: '10px' }, children: [_jsx("div", { style: {
|
|
218
211
|
width: 'calc(100% - 60px)',
|
|
219
212
|
overflowX: 'auto',
|
|
220
213
|
whiteSpace: 'nowrap',
|
|
@@ -229,14 +222,22 @@ const TMBlogCommentForm = (props) => {
|
|
|
229
222
|
const tooltipContent = (_jsxs("div", { style: { textAlign: 'left' }, children: [_jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Name, ":"] }), " ", draft.name ?? '-'] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Author, ":"] }), " ", draft.updaterName ?? '-'] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Version, ":"] }), " ", draft.version] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Size, ":"] }), " ", formatBytes(draft.size ?? 0)] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.CreationTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(draft.creationTime)] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.LastUpdateTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(draft.lastUpdateTime)] })] }));
|
|
230
223
|
return _jsxs("div", { style: {
|
|
231
224
|
display: 'inline-flex',
|
|
232
|
-
alignItems: 'center',
|
|
233
|
-
padding: '8px
|
|
234
|
-
|
|
225
|
+
alignItems: 'center', // <-- this centers content vertically
|
|
226
|
+
padding: '4px 8px',
|
|
227
|
+
margin: '4px',
|
|
235
228
|
border: '1px solid #ddd',
|
|
236
229
|
borderRadius: '8px',
|
|
230
|
+
boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
|
|
231
|
+
cursor: 'pointer',
|
|
232
|
+
fontSize: '0.9rem',
|
|
237
233
|
backgroundColor: '#fff',
|
|
238
|
-
|
|
239
|
-
|
|
234
|
+
}, onMouseEnter: (e) => {
|
|
235
|
+
e.currentTarget.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.15)';
|
|
236
|
+
e.currentTarget.style.backgroundColor = '#cfcfcf';
|
|
237
|
+
}, onMouseLeave: (e) => {
|
|
238
|
+
e.currentTarget.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
|
|
239
|
+
e.currentTarget.style.backgroundColor = '#fff';
|
|
240
|
+
}, children: [draft.ext ? (_jsx("span", { style: { marginRight: '10px', display: 'flex', alignItems: 'center' }, children: getFileIcon(draft.ext, undefined, tooltipContent) })) : (_jsx(IconAttachment, { style: { marginRight: '5px' } })), _jsx("span", { style: { marginRight: '8px', display: 'flex', alignItems: 'center' }, children: draft.name }), draft.version && (_jsx("span", { style: {
|
|
240
241
|
display: 'inline-flex',
|
|
241
242
|
width: '20px',
|
|
242
243
|
height: '20px',
|
|
@@ -248,7 +249,7 @@ const TMBlogCommentForm = (props) => {
|
|
|
248
249
|
fontWeight: 'bold',
|
|
249
250
|
marginRight: '8px',
|
|
250
251
|
boxShadow: '1px 1px 2px #00000020',
|
|
251
|
-
}, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Version, children: draft.version }) }), _jsx(TMTooltip, { content: SDKUI_Localizator.RemoveAttachment, children: _jsx("span", { onClick: () => removeAttachment(draft), style: {
|
|
252
|
+
}, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Version, children: draft.version }) })), _jsx(TMTooltip, { content: SDKUI_Localizator.RemoveAttachment, children: _jsx("span", { onClick: () => removeAttachment(draft), style: {
|
|
252
253
|
display: 'inline-flex',
|
|
253
254
|
width: '20px',
|
|
254
255
|
height: '20px',
|
|
@@ -259,21 +260,36 @@ const TMBlogCommentForm = (props) => {
|
|
|
259
260
|
borderRadius: '30px',
|
|
260
261
|
cursor: 'pointer',
|
|
261
262
|
boxShadow: '1px 1px 2px #00000020',
|
|
262
|
-
}, children: _jsx("span", { style: { fontSize:
|
|
263
|
-
})) : (_jsx("div", { style: { color: '#999', width: '100%', textAlign: 'center' }, children: SDKUI_Localizator.NoAttachments })) }), _jsx(TMTooltip, { content: SDKUI_Localizator.Attachments, children: _jsx("i", { className: "dx-icon-attach", style: {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
263
|
+
}, children: _jsx("span", { style: { fontSize: '15px' }, children: "\u00D7" }) }) })] }, draft.did);
|
|
264
|
+
})) : (_jsx("div", { style: { color: '#999', width: '100%', textAlign: 'center' }, children: SDKUI_Localizator.NoAttachments })) }), _jsx(TMTooltip, { content: SDKUI_Localizator.Attachments + ": " + currentDraftAttachments.length, children: _jsxs("div", { style: { position: 'relative', display: 'inline-block' }, children: [_jsx("i", { className: "dx-icon-attach", style: {
|
|
265
|
+
width: '50px',
|
|
266
|
+
height: '50px',
|
|
267
|
+
marginLeft: '10px',
|
|
268
|
+
fontSize: '20px',
|
|
269
|
+
cursor: 'pointer',
|
|
270
|
+
border: '1px solid #ccc',
|
|
271
|
+
borderRadius: '8px',
|
|
272
|
+
backgroundColor: '#f9f9f9',
|
|
273
|
+
display: 'flex',
|
|
274
|
+
alignItems: 'center',
|
|
275
|
+
justifyContent: 'center',
|
|
276
|
+
transition: 'all 0.2s ease-in-out',
|
|
277
|
+
}, onMouseOver: (e) => (e.currentTarget.style.backgroundColor = '#e6f7ff'), onMouseOut: (e) => (e.currentTarget.style.backgroundColor = '#f9f9f9'), onClick: () => setShowAttachmentsForm(true) }), currentDraftAttachments.length > 0 && (_jsx("span", { style: {
|
|
278
|
+
position: 'absolute',
|
|
279
|
+
top: '-5px',
|
|
280
|
+
right: '-5px',
|
|
281
|
+
backgroundColor: '#203E5A',
|
|
282
|
+
color: 'white',
|
|
283
|
+
borderRadius: '50%',
|
|
284
|
+
minWidth: '20px',
|
|
285
|
+
height: '20px',
|
|
286
|
+
display: 'flex',
|
|
287
|
+
alignItems: 'center',
|
|
288
|
+
justifyContent: 'center',
|
|
289
|
+
padding: '0 6px',
|
|
290
|
+
fontSize: '12px',
|
|
291
|
+
fontWeight: 'bold',
|
|
292
|
+
}, children: currentDraftAttachments.length > 99 ? '99+' : currentDraftAttachments.length }))] }) })] })] }), showAttachmentsForm && _jsx(TMAttachmentsView, { dataSource: dataSource, selectedIDs: currentDraftAttachments.map(draft => draft.id), onChoose: onChoose, onClose: () => setShowAttachmentsForm(false) })] }) });
|
|
277
293
|
};
|
|
278
294
|
export default TMBlogCommentForm;
|
|
279
295
|
const TMAttachmentsView = (props) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { LayoutModes, SearchResultDescriptor, TaskDescriptor } from '@topconsultnpm/sdk-ts';
|
|
3
|
-
import { DcmtInfo, FormModes, TaskContext } from '../../../ts';
|
|
2
|
+
import { LayoutModes, ObjectRef, SearchResultDescriptor, TaskDescriptor, ValidationItem } from '@topconsultnpm/sdk-ts';
|
|
3
|
+
import { DcmtInfo, FormModes, MetadataValueDescriptorEx, TaskContext } from '../../../ts';
|
|
4
4
|
interface ITMDcmtFormProps {
|
|
5
5
|
TID?: number;
|
|
6
6
|
DID?: number;
|
|
@@ -20,6 +20,7 @@ interface ITMDcmtFormProps {
|
|
|
20
20
|
invokedByTodo?: boolean;
|
|
21
21
|
taskFormDialogComponent?: React.ReactNode;
|
|
22
22
|
taskMoreInfo?: TaskDescriptor;
|
|
23
|
+
showBackButton?: boolean;
|
|
23
24
|
onNext?: () => void;
|
|
24
25
|
onPrev?: () => void;
|
|
25
26
|
onClose?: () => void;
|
|
@@ -44,7 +45,13 @@ interface ITMDcmtFormProps {
|
|
|
44
45
|
passToSearch?: (outputMids: Array<{
|
|
45
46
|
mid: number;
|
|
46
47
|
value: string;
|
|
47
|
-
}
|
|
48
|
+
}>, tid?: number) => void;
|
|
49
|
+
isSharedDcmt?: boolean;
|
|
50
|
+
sharedSourceTID?: number;
|
|
51
|
+
sharedSourceDID?: number;
|
|
52
|
+
allowButtonsRefs?: boolean;
|
|
53
|
+
onReferenceClick?: (ref: ObjectRef) => void;
|
|
48
54
|
}
|
|
49
55
|
declare const TMDcmtForm: React.FC<ITMDcmtFormProps>;
|
|
50
56
|
export default TMDcmtForm;
|
|
57
|
+
export declare const validateMetadataList: (mvdList?: MetadataValueDescriptorEx[]) => ValidationItem[];
|