@topconsultnpm/sdkui-react 6.19.0-dev1.36 → 6.19.0-dev1.38
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/editors/TMHtmlEditor.d.ts +5 -0
- package/lib/components/editors/TMHtmlEditor.js +70 -12
- package/lib/components/features/blog/TMBlogCommentForm.js +53 -43
- package/lib/components/features/search/TMSearchResult.js +12 -7
- package/lib/css/tm-sdkui.css +1 -1
- package/lib/helper/SDKUI_Localizator.d.ts +1 -1
- package/lib/helper/SDKUI_Localizator.js +6 -6
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ValidationItem } from '@topconsultnpm/sdk-ts';
|
|
2
|
+
export declare const sanitizeAndFormatComment: (raw?: string) => string;
|
|
2
3
|
export interface ITMHtmlEditor {
|
|
3
4
|
/** Width of the editor (e.g., '100%', '500px') */
|
|
4
5
|
width?: string;
|
|
@@ -28,6 +29,10 @@ export interface ITMHtmlEditor {
|
|
|
28
29
|
toolbarMode?: 'compact' | 'expanded';
|
|
29
30
|
/** If true, the editor will be focused on mount */
|
|
30
31
|
autoFocus?: boolean;
|
|
32
|
+
/** Maximum number of characters allowed in the editor */
|
|
33
|
+
maxLength?: number;
|
|
34
|
+
/** If true, displays a character count below the editor */
|
|
35
|
+
showCount?: boolean;
|
|
31
36
|
}
|
|
32
37
|
declare const TMHtmlEditor: (props: ITMHtmlEditor) => import("react/jsx-runtime").JSX.Element;
|
|
33
38
|
export default TMHtmlEditor;
|
|
@@ -4,8 +4,33 @@ 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
|
+
// Replace </p> with '' only if followed by <ol> or <ul>
|
|
15
|
+
.replace(/<\/p>(?=\s*<(ol|ul)>)/gi, '')
|
|
16
|
+
// Replace all other </p> with '\r\n'
|
|
17
|
+
.replace(/<\/p>/gi, '\r\n')
|
|
18
|
+
// Remove all <p> tags
|
|
19
|
+
.replace(/<p>/gi, '')
|
|
20
|
+
// Remove all <br> tags
|
|
21
|
+
.replace(/<br>/gi, '')
|
|
22
|
+
// Trim whitespace
|
|
23
|
+
.trim();
|
|
24
|
+
// Remove dangerous HTML elements
|
|
25
|
+
cleanComment = cleanComment.replace(/<(script|iframe|embed|object|link|style|img|video|audio|svg|form|input|button|textarea|select|pre|function)[^>]*>/gi, '');
|
|
26
|
+
return cleanComment;
|
|
27
|
+
};
|
|
7
28
|
const TMHtmlEditor = (props) => {
|
|
8
|
-
const { width = "100%", height = "100%", initialMarkup = "", mentionsConfig, onValueChanged, validationItems = [], isEditorEnabled: isEditorEnabledProp = false, toolbarMode = 'compact', autoFocus = false } = props;
|
|
29
|
+
const { width = "100%", height = "100%", initialMarkup = "", mentionsConfig, onValueChanged, validationItems = [], isEditorEnabled: isEditorEnabledProp = false, toolbarMode = 'compact', autoFocus = false, maxLength = 1000, showCount = true, } = props;
|
|
30
|
+
// Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
|
|
31
|
+
const deviceType = useDeviceType();
|
|
32
|
+
// This avoids unnecessary re-renders by only recalculating when deviceType changes.
|
|
33
|
+
let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
|
|
9
34
|
// Ref for HtmlEditor instance
|
|
10
35
|
const editorRef = useRef(null);
|
|
11
36
|
// State for editor enable/disable
|
|
@@ -14,13 +39,15 @@ const TMHtmlEditor = (props) => {
|
|
|
14
39
|
const [markup, setMarkup] = useState(initialMarkup);
|
|
15
40
|
// State to track the position (x, y coordinates) where the custom context menu should be displayed.
|
|
16
41
|
const [contextMenuPos, setContextMenuPos] = useState(null);
|
|
17
|
-
// State to
|
|
18
|
-
const [
|
|
42
|
+
// State to track remaining characters
|
|
43
|
+
const [charactersRemaining, setCharactersRemaining] = useState(maxLength - initialMarkup.length);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const cleanedMarkup = sanitizeAndFormatComment(markup);
|
|
46
|
+
setCharactersRemaining(maxLength - cleanedMarkup.length);
|
|
47
|
+
}, [markup, maxLength]);
|
|
19
48
|
// Function to read text from the clipboard, format it, and paste into the Quill editor
|
|
20
49
|
const pasteFromClipboard = async () => {
|
|
21
50
|
try {
|
|
22
|
-
// Set flag to indicate paste operation is in progress
|
|
23
|
-
setIsPasting(true);
|
|
24
51
|
// Read plain text from the clipboard asynchronously
|
|
25
52
|
let text = await navigator.clipboard.readText();
|
|
26
53
|
text = '<p>' + text.replace(/\r\n/g, '</p><p>') + '</p>';
|
|
@@ -52,10 +79,6 @@ const TMHtmlEditor = (props) => {
|
|
|
52
79
|
// Log any errors that might occur during clipboard access or pasting
|
|
53
80
|
console.warn('Clipboard paste failed:', err);
|
|
54
81
|
}
|
|
55
|
-
finally {
|
|
56
|
-
// Reset paste state after a short delay to restore UI state
|
|
57
|
-
setTimeout(() => setIsPasting(false), 500);
|
|
58
|
-
}
|
|
59
82
|
};
|
|
60
83
|
useEffect(() => {
|
|
61
84
|
const handleKeyDown = (e) => {
|
|
@@ -116,7 +139,7 @@ const TMHtmlEditor = (props) => {
|
|
|
116
139
|
}, [autoFocus]);
|
|
117
140
|
// Memoized check for validation errors
|
|
118
141
|
const hasValidationErrors = useMemo(() => {
|
|
119
|
-
return
|
|
142
|
+
return validationItems && validationItems.length > 0;
|
|
120
143
|
}, [validationItems]);
|
|
121
144
|
// Handler function triggered by the context menu's "Paste" action
|
|
122
145
|
const handlePaste = async () => {
|
|
@@ -125,9 +148,44 @@ const TMHtmlEditor = (props) => {
|
|
|
125
148
|
// Close the custom context menu after pasting
|
|
126
149
|
setContextMenuPos(null);
|
|
127
150
|
};
|
|
128
|
-
return (_jsxs("div", { style: {
|
|
151
|
+
return (_jsxs("div", { style: {
|
|
152
|
+
height: height,
|
|
153
|
+
width: width
|
|
154
|
+
}, children: [_jsx("div", { className: "custom-mentions-wrapper", onContextMenu: handleContextMenu, style: {
|
|
155
|
+
borderWidth: '1px',
|
|
156
|
+
borderStyle: 'solid',
|
|
157
|
+
borderColor: hasValidationErrors ? "red" : "#e0e0e0 #e0e0e0 #616161",
|
|
158
|
+
width: "100%",
|
|
159
|
+
height: `calc(100% - ${showCount ? 15 : 0}px - ${validationItems.length > 0 ? 15 : 0}px)`,
|
|
160
|
+
}, 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
161
|
_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" })] })) }) }),
|
|
162
|
+
_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 ? ((() => {
|
|
163
|
+
const cleanedMarkup = sanitizeAndFormatComment(markup);
|
|
164
|
+
const showInfoIcon = charactersRemaining !== maxLength;
|
|
165
|
+
return (_jsxs("div", { style: {
|
|
166
|
+
display: 'flex',
|
|
167
|
+
alignItems: 'center',
|
|
168
|
+
justifyContent: 'flex-end',
|
|
169
|
+
fontSize: 12,
|
|
170
|
+
color: '#6c757d',
|
|
171
|
+
marginTop: 4,
|
|
172
|
+
gap: 4,
|
|
173
|
+
}, 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: () => {
|
|
174
|
+
TMMessageBoxManager.show({
|
|
175
|
+
title: 'Markup HTML',
|
|
176
|
+
initialWidth: !isMobile ? '700px' : undefined,
|
|
177
|
+
message: (_jsx("pre", { style: {
|
|
178
|
+
whiteSpace: 'pre-wrap',
|
|
179
|
+
background: '#f5f5f5',
|
|
180
|
+
padding: '12px',
|
|
181
|
+
borderRadius: '6px',
|
|
182
|
+
}, children: cleanedMarkup })),
|
|
183
|
+
resizable: true,
|
|
184
|
+
showToppy: false,
|
|
185
|
+
buttons: [ButtonNames.OK],
|
|
186
|
+
});
|
|
187
|
+
} }) }))] }));
|
|
188
|
+
})()) : null, validationItems.length > 0 && _jsx(TMVilViewer, { vil: validationItems }), contextMenuPos &&
|
|
131
189
|
ReactDOM.createPortal(_jsxs("div", { style: {
|
|
132
190
|
position: 'fixed',
|
|
133
191
|
top: contextMenuPos.y,
|
|
@@ -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,20 +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
|
-
// Imposta la lunghezza massima consentita per il commento
|
|
48
|
-
const maxLength = 1000;
|
|
49
49
|
// Calcola la lunghezza effettiva del commento inserito
|
|
50
|
-
const commentLength =
|
|
51
|
-
|
|
52
|
-
const exceededLength = commentLength - maxLength;
|
|
50
|
+
const commentLength = cleanedMarkup.length;
|
|
51
|
+
const exceededChars = commentLength - maxLength;
|
|
53
52
|
// Validate description length (max 1000)
|
|
54
53
|
if (commentLength > maxLength) {
|
|
55
|
-
vil.push(new ValidationItem(ResultTypes.ERROR, SDKUI_Localizator.Comment, `${SDKUI_Localizator.DescriptionLengthExceededMessage.replaceParams(
|
|
54
|
+
vil.push(new ValidationItem(ResultTypes.ERROR, SDKUI_Localizator.Comment, `${SDKUI_Localizator.DescriptionLengthExceededMessage.replaceParams(exceededChars)}`));
|
|
56
55
|
}
|
|
57
56
|
// Detect dangerous HTML tags
|
|
58
57
|
const tagRegex = /<\/?(script|iframe|embed|object|link|style|img|video|audio|svg|form|input|button|textarea|select|pre|function)[^>]*>/gi;
|
|
@@ -115,19 +114,7 @@ const TMBlogCommentForm = (props) => {
|
|
|
115
114
|
// Retrieve the comment from formData, or use an empty string if undefined
|
|
116
115
|
const comment = formData?.comment ?? "";
|
|
117
116
|
// Clean the comment by removing <p> tags and replacing </p> with line breaks
|
|
118
|
-
|
|
119
|
-
// Replace </p> with '' only if followed by <ol> or <ul>
|
|
120
|
-
.replace(/<\/p>(?=\s*<(ol|ul)>)/gi, '')
|
|
121
|
-
// Replace all other </p> with '\r\n'
|
|
122
|
-
.replace(/<\/p>/gi, '\r\n')
|
|
123
|
-
// Remove all <p> tags
|
|
124
|
-
.replace(/<p>/gi, '')
|
|
125
|
-
// Remove all <br> tags
|
|
126
|
-
.replace(/<br>/gi, '')
|
|
127
|
-
// Trim whitespace
|
|
128
|
-
.trim();
|
|
129
|
-
// Validate and remove any potentially dangerous HTML tags (like <script>, <iframe>, etc.)
|
|
130
|
-
cleanComment = cleanComment.replace(/<(script|iframe|embed|object|link|style|img|video|audio|svg|form|input|button|textarea|select|pre|function)[^>]*>/gi, '');
|
|
117
|
+
const cleanComment = sanitizeAndFormatComment(comment);
|
|
131
118
|
// Assign the cleaned comment as the description for the blog post
|
|
132
119
|
blogPost.description = cleanComment ?? "";
|
|
133
120
|
// If there are file items (attachments), process them
|
|
@@ -220,7 +207,7 @@ const TMBlogCommentForm = (props) => {
|
|
|
220
207
|
// Update the state with selected draft items
|
|
221
208
|
setCurrentDraftAttachments(selectedDraftItems);
|
|
222
209
|
};
|
|
223
|
-
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: {
|
|
224
211
|
width: 'calc(100% - 60px)',
|
|
225
212
|
overflowX: 'auto',
|
|
226
213
|
whiteSpace: 'nowrap',
|
|
@@ -235,14 +222,22 @@ const TMBlogCommentForm = (props) => {
|
|
|
235
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)] })] }));
|
|
236
223
|
return _jsxs("div", { style: {
|
|
237
224
|
display: 'inline-flex',
|
|
238
|
-
alignItems: 'center',
|
|
239
|
-
padding: '8px
|
|
240
|
-
|
|
225
|
+
alignItems: 'center', // <-- this centers content vertically
|
|
226
|
+
padding: '4px 8px',
|
|
227
|
+
margin: '4px',
|
|
241
228
|
border: '1px solid #ddd',
|
|
242
229
|
borderRadius: '8px',
|
|
230
|
+
boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
|
|
231
|
+
cursor: 'pointer',
|
|
232
|
+
fontSize: '0.9rem',
|
|
243
233
|
backgroundColor: '#fff',
|
|
244
|
-
|
|
245
|
-
|
|
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: {
|
|
246
241
|
display: 'inline-flex',
|
|
247
242
|
width: '20px',
|
|
248
243
|
height: '20px',
|
|
@@ -254,7 +249,7 @@ const TMBlogCommentForm = (props) => {
|
|
|
254
249
|
fontWeight: 'bold',
|
|
255
250
|
marginRight: '8px',
|
|
256
251
|
boxShadow: '1px 1px 2px #00000020',
|
|
257
|
-
}, 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: {
|
|
258
253
|
display: 'inline-flex',
|
|
259
254
|
width: '20px',
|
|
260
255
|
height: '20px',
|
|
@@ -265,21 +260,36 @@ const TMBlogCommentForm = (props) => {
|
|
|
265
260
|
borderRadius: '30px',
|
|
266
261
|
cursor: 'pointer',
|
|
267
262
|
boxShadow: '1px 1px 2px #00000020',
|
|
268
|
-
}, children: _jsx("span", { style: { fontSize:
|
|
269
|
-
})) : (_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: {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
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) })] }) });
|
|
283
293
|
};
|
|
284
294
|
export default TMBlogCommentForm;
|
|
285
295
|
const TMAttachmentsView = (props) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
|
-
import { SDK_Globals, DataColumnTypes, MetadataDataDomains, DataListViewModes, MetadataFormats, LayoutModes, TemplateTIDs, DcmtTypeListCacheService, AccessLevels, SystemMIDsAsNumber } from '@topconsultnpm/sdk-ts';
|
|
3
|
+
import { SDK_Globals, DataColumnTypes, MetadataDataDomains, DataListViewModes, MetadataFormats, LayoutModes, TemplateTIDs, DcmtTypeListCacheService, AccessLevels, SystemMIDsAsNumber, RetrieveFileOptions, DcmtOpers, GeneralRetrieveFormats } from '@topconsultnpm/sdk-ts';
|
|
4
4
|
import styled from 'styled-components';
|
|
5
5
|
import { getCommandsMenuItems, getSelectedDcmtsOrFocused } from './TMSearchResultsMenuItems';
|
|
6
6
|
import { genUniqueId, IconShow, IconBoard, IconDcmtTypeSys, IconDetailDcmts, SDKUI_Localizator, IconDelete, IconRefresh, IconMenuVertical, IconDownload, deepCompare, getDataColumnName, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, IconSearchCheck, TMCommandsContextMenu } from '../../../helper';
|
|
@@ -153,15 +153,20 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
|
|
|
153
153
|
const openSharedArchiveHandler = async () => {
|
|
154
154
|
const dcmts = getSelectedDcmtsOrFocused(selectedItems, focusedItem);
|
|
155
155
|
if (dcmts.length === 0) {
|
|
156
|
-
ShowAlert({ message: "Nessun documento selezionato", mode: "warning", duration: 3000 });
|
|
156
|
+
ShowAlert({ message: "Nessun documento selezionato", mode: "warning", title: 'Archivio Condivisa', duration: 3000 });
|
|
157
157
|
return;
|
|
158
158
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
159
|
+
try {
|
|
160
|
+
const rfo = new RetrieveFileOptions();
|
|
161
|
+
rfo.retrieveReason = DcmtOpers.None;
|
|
162
|
+
rfo.generalRetrieveFormat = GeneralRetrieveFormats.OriginalUnsigned;
|
|
163
|
+
let dcmtFile = await getDcmtFileAsync({ TID: focusedItem?.TID, DID: focusedItem?.DID }, rfo, 'Archiviazione Condivisa', false, true);
|
|
164
|
+
if (dcmtFile) {
|
|
165
|
+
setSharedDcmtFile(dcmtFile?.file);
|
|
166
|
+
}
|
|
162
167
|
}
|
|
163
|
-
|
|
164
|
-
ShowAlert({ message:
|
|
168
|
+
catch (error) {
|
|
169
|
+
ShowAlert({ message: 'Il Documenti ha solo i metadati', mode: "warning", title: 'Archivio Condivisa', duration: 5000 });
|
|
165
170
|
}
|
|
166
171
|
setIsOpenSharedArchive(true);
|
|
167
172
|
};
|
package/lib/css/tm-sdkui.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@import"https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,300;1,400;1,500;1,600;1,700;1,800&display=swap";@import"https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,300;1,400;1,500;1,600;1,700;1,800&display=swap";*{margin:0;padding:0;box-sizing:border-box;font-family:"Open Sans",sans-serif}.tm-tooltip-container-base,.tm-tooltip-container-base-right,.tm-tooltip-container-base-bottom,.tm-tooltip-container-base-left,.tm-tooltip-container-base-top{position:absolute;width:max-content;height:max-content;border-radius:5px;user-select:none;z-index:20000070}.tm-tooltip-container-base-top{top:-0.8rem;left:0;transform:translateY(-100%)}.tm-tooltip-container-base-left{left:-0.8rem;top:0;transform:translateX(-100%)}.tm-tooltip-container-base-bottom{bottom:-0.8rem;left:0;transform:translateY(100%)}.tm-tooltip-container-base-right{right:-0.8rem;top:0;transform:translateX(100%)}.tm-tooltip-arrow,.tm-tooltip-arrow-right,.tm-tooltip-arrow-left,.tm-tooltip-arrow-top,.tm-tooltip-arrow-bottom{position:absolute;width:0;height:0;z-index:50000}.tm-tooltip-arrow-bottom{top:-8px;left:8px;border-bottom:9px solid #fff;border-left:9px solid rgba(0,0,0,0);border-right:9px solid rgba(0,0,0,0)}.tm-tooltip-arrow-top{bottom:-8px;left:8px;border-top:9px solid #fff;border-left:9px solid rgba(0,0,0,0);border-right:9px solid rgba(0,0,0,0)}.tm-tooltip-arrow-left{top:8px;right:-8px;border-left:9px solid #fff;border-top:9px solid rgba(0,0,0,0);border-bottom:9px solid rgba(0,0,0,0)}.tm-tooltip-arrow-right{top:8px;left:-8px;border-right:9px solid #fff;border-top:9px solid rgba(0,0,0,0);border-bottom:9px solid rgba(0,0,0,0)}#user-credentials-popup .dx-accordion-item-title::before{content:none !important}*{margin:0;padding:0;box-sizing:border-box;font-family:"Open Sans",sans-serif}.tm-tooltip-container-base,.tm-tooltip-container-base-top,.tm-tooltip-container-base-left,.tm-tooltip-container-base-bottom,.tm-tooltip-container-base-right{position:absolute;width:max-content;height:max-content;border-radius:5px;user-select:none;z-index:20000070}.tm-tooltip-container-base-top{top:-0.8rem;left:0;transform:translateY(-100%)}.tm-tooltip-container-base-left{left:-0.8rem;top:0;transform:translateX(-100%)}.tm-tooltip-container-base-bottom{bottom:-0.8rem;left:0;transform:translateY(100%)}.tm-tooltip-container-base-right{right:-0.8rem;top:0;transform:translateX(100%)}.tm-tooltip-arrow,.tm-tooltip-arrow-bottom,.tm-tooltip-arrow-top,.tm-tooltip-arrow-left,.tm-tooltip-arrow-right{position:absolute;width:0;height:0;z-index:50000}.tm-tooltip-arrow-bottom{top:-8px;left:8px;border-bottom:9px solid #fff;border-left:9px solid rgba(0,0,0,0);border-right:9px solid rgba(0,0,0,0)}.tm-tooltip-arrow-top{bottom:-8px;left:8px;border-top:9px solid #fff;border-left:9px solid rgba(0,0,0,0);border-right:9px solid rgba(0,0,0,0)}.tm-tooltip-arrow-left{top:8px;right:-8px;border-left:9px solid #fff;border-top:9px solid rgba(0,0,0,0);border-bottom:9px solid rgba(0,0,0,0)}.tm-tooltip-arrow-right{top:8px;left:-8px;border-right:9px solid #fff;border-top:9px solid rgba(0,0,0,0);border-bottom:9px solid rgba(0,0,0,0)}#user-credentials-popup .dx-accordion-item-title::before{content:none !important}@keyframes show-error{0%{display:none;opacity:0;z-index:20000999}5%{display:block;opacity:1;z-index:20000999}95%{display:block;opacity:1;z-index:20000999}100%{opacity:0;display:none;z-index:20000999}}.tm-alert-animation-style{animation:show-error both;animation-timing-function:linear;animation-iteration-count:none;z-index:20000999}.tm-alert-container{position:absolute;width:100%;height:100%;z-index:20000999}@keyframes loading{from{width:0}to{width:100%}}.tm-alert-loading{width:100%;height:5px;position:absolute;bottom:0;left:0;animation:loading;animation-duration:5000ms}.tm-alert-icon{position:absolute;width:22px;height:22px;background-color:#fff;top:"20px";left:"20px";border-radius:50%;display:flex;align-items:center;justify-content:center}.dx-context-menu.dx-overlay-content{height:auto !important;max-height:none !important}.dx-context-menu .dx-menu-items-container{max-height:none !important}
|
|
1
|
+
@import"https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,300;1,400;1,500;1,600;1,700;1,800&display=swap";@import"https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,300;1,400;1,500;1,600;1,700;1,800&display=swap";*{margin:0;padding:0;box-sizing:border-box;font-family:"Open Sans",sans-serif}.tm-tooltip-container-base,.tm-tooltip-container-base-right,.tm-tooltip-container-base-bottom,.tm-tooltip-container-base-left,.tm-tooltip-container-base-top{position:absolute;width:max-content;height:max-content;border-radius:5px;user-select:none;z-index:20000070}.tm-tooltip-container-base-top{top:-0.8rem;left:0;transform:translateY(-100%)}.tm-tooltip-container-base-left{left:-0.8rem;top:0;transform:translateX(-100%)}.tm-tooltip-container-base-bottom{bottom:-0.8rem;left:0;transform:translateY(100%)}.tm-tooltip-container-base-right{right:-0.8rem;top:0;transform:translateX(100%)}.tm-tooltip-arrow,.tm-tooltip-arrow-right,.tm-tooltip-arrow-left,.tm-tooltip-arrow-top,.tm-tooltip-arrow-bottom{position:absolute;width:0;height:0;z-index:50000}.tm-tooltip-arrow-bottom{top:-8px;left:8px;border-bottom:9px solid #fff;border-left:9px solid rgba(0,0,0,0);border-right:9px solid rgba(0,0,0,0)}.tm-tooltip-arrow-top{bottom:-8px;left:8px;border-top:9px solid #fff;border-left:9px solid rgba(0,0,0,0);border-right:9px solid rgba(0,0,0,0)}.tm-tooltip-arrow-left{top:8px;right:-8px;border-left:9px solid #fff;border-top:9px solid rgba(0,0,0,0);border-bottom:9px solid rgba(0,0,0,0)}.tm-tooltip-arrow-right{top:8px;left:-8px;border-right:9px solid #fff;border-top:9px solid rgba(0,0,0,0);border-bottom:9px solid rgba(0,0,0,0)}#user-credentials-popup .dx-accordion-item-title::before{content:none !important}*{margin:0;padding:0;box-sizing:border-box;font-family:"Open Sans",sans-serif}.tm-tooltip-container-base,.tm-tooltip-container-base-top,.tm-tooltip-container-base-left,.tm-tooltip-container-base-bottom,.tm-tooltip-container-base-right{position:absolute;width:max-content;height:max-content;border-radius:5px;user-select:none;z-index:20000070}.tm-tooltip-container-base-top{top:-0.8rem;left:0;transform:translateY(-100%)}.tm-tooltip-container-base-left{left:-0.8rem;top:0;transform:translateX(-100%)}.tm-tooltip-container-base-bottom{bottom:-0.8rem;left:0;transform:translateY(100%)}.tm-tooltip-container-base-right{right:-0.8rem;top:0;transform:translateX(100%)}.tm-tooltip-arrow,.tm-tooltip-arrow-bottom,.tm-tooltip-arrow-top,.tm-tooltip-arrow-left,.tm-tooltip-arrow-right{position:absolute;width:0;height:0;z-index:50000}.tm-tooltip-arrow-bottom{top:-8px;left:8px;border-bottom:9px solid #fff;border-left:9px solid rgba(0,0,0,0);border-right:9px solid rgba(0,0,0,0)}.tm-tooltip-arrow-top{bottom:-8px;left:8px;border-top:9px solid #fff;border-left:9px solid rgba(0,0,0,0);border-right:9px solid rgba(0,0,0,0)}.tm-tooltip-arrow-left{top:8px;right:-8px;border-left:9px solid #fff;border-top:9px solid rgba(0,0,0,0);border-bottom:9px solid rgba(0,0,0,0)}.tm-tooltip-arrow-right{top:8px;left:-8px;border-right:9px solid #fff;border-top:9px solid rgba(0,0,0,0);border-bottom:9px solid rgba(0,0,0,0)}#user-credentials-popup .dx-accordion-item-title::before{content:none !important}@keyframes show-error{0%{display:none;opacity:0;z-index:20000999}5%{display:block;opacity:1;z-index:20000999}95%{display:block;opacity:1;z-index:20000999}100%{opacity:0;display:none;z-index:20000999}}.tm-alert-animation-style{animation:show-error both;animation-timing-function:linear;animation-iteration-count:none;z-index:20000999}.tm-alert-container{position:absolute;width:100%;height:100%;z-index:20000999}@keyframes loading{from{width:0}to{width:100%}}.tm-alert-loading{width:100%;height:5px;position:absolute;bottom:0;left:0;animation:loading;animation-duration:5000ms}.tm-alert-icon{position:absolute;width:22px;height:22px;background-color:#fff;top:"20px";left:"20px";border-radius:50%;display:flex;align-items:center;justify-content:center}.dx-context-menu.dx-overlay-content{height:auto !important;max-height:none !important}.dx-context-menu .dx-menu-items-container{max-height:none !important}.custom-mentions-wrapper span.dx-mention span[contenteditable=false]>span:first-child{font-size:0;width:0;display:inline-block;overflow:hidden}.custom-mentions-wrapper span.dx-mention{color:#2559a5;font-weight:bold;background-color:rgba(0,0,0,0)}
|
|
@@ -132,7 +132,7 @@ export declare class SDKUI_Localizator {
|
|
|
132
132
|
static get DeletionOperationInterrupted(): "Löschvorgang abgebrochen" | "Deletion operation interrupted" | "Operación de eliminación interrumpida" | "Opération de suppression interrompue" | "Operação de exclusão interrompida" | "Operazione di eliminazione interrotta";
|
|
133
133
|
static get Deny(): "Ablehnen" | "Deny" | "Denegar" | "Refuser" | "Negar" | "Negato";
|
|
134
134
|
static get Description(): "Beschreibung" | "Description" | "Descripción" | "Descrição" | "Descrizione";
|
|
135
|
-
static get DescriptionLengthExceededMessage(): "Die Beschreibung ist zu lang: {{0}}
|
|
135
|
+
static get DescriptionLengthExceededMessage(): "Die Beschreibung ist zu lang: {{0}} Zeichen zu viel" | "Description is too long: {{0}} characters too many" | "La descripción es demasiado larga: {{0}} caracteres de más" | "La description est trop longue : {{0}} caractères en trop" | "A descrição é demasiado longa: {{0}} caracteres a mais" | "La descrizione è troppo lunga: {{0}} caratteri in più";
|
|
136
136
|
static get DescriptionTooLongMessage(): "Die Beschreibung ist zu lang: Maximal {{0}' Zeichen" | "Description is too long: Max {{0}} characters" | "La descripción es demasiado larga: Máximo {{0}} caracteres" | "La description est trop longue : Maximum {{0}} caractères" | "A descrição é demasiado longa: Máximo {{0}} caracteres" | "La descrizione è troppo lunga: Massimo {{0}} caratteri";
|
|
137
137
|
static get Design(): "Design" | "Diseño" | "Conception" | "Projeto" | "Progettazione";
|
|
138
138
|
static get Destination(): "Bestimmung" | "Destination" | "Destino" | "Destinazione";
|
|
@@ -1278,17 +1278,17 @@ export class SDKUI_Localizator {
|
|
|
1278
1278
|
static get DescriptionLengthExceededMessage() {
|
|
1279
1279
|
switch (this._cultureID) {
|
|
1280
1280
|
case CultureIDs.De_DE:
|
|
1281
|
-
return "Die Beschreibung ist zu lang: {{0}}
|
|
1281
|
+
return "Die Beschreibung ist zu lang: {{0}} Zeichen zu viel";
|
|
1282
1282
|
case CultureIDs.En_US:
|
|
1283
|
-
return "Description is too long: {{0}}
|
|
1283
|
+
return "Description is too long: {{0}} characters too many";
|
|
1284
1284
|
case CultureIDs.Es_ES:
|
|
1285
|
-
return "La descripción es demasiado larga: {{0}}
|
|
1285
|
+
return "La descripción es demasiado larga: {{0}} caracteres de más";
|
|
1286
1286
|
case CultureIDs.Fr_FR:
|
|
1287
|
-
return "La description est trop longue : {{0}}
|
|
1287
|
+
return "La description est trop longue : {{0}} caractères en trop";
|
|
1288
1288
|
case CultureIDs.Pt_PT:
|
|
1289
|
-
return "A descrição é demasiado longa: {{0}}
|
|
1289
|
+
return "A descrição é demasiado longa: {{0}} caracteres a mais";
|
|
1290
1290
|
default:
|
|
1291
|
-
return "La descrizione è troppo lunga: {{0}}
|
|
1291
|
+
return "La descrizione è troppo lunga: {{0}} caratteri in più";
|
|
1292
1292
|
}
|
|
1293
1293
|
}
|
|
1294
1294
|
static get DescriptionTooLongMessage() {
|