@topconsultnpm/sdkui-react-beta 6.14.90 → 6.14.91
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.js +2 -2
- package/lib/components/features/blog/TMBlogCommentForm.d.ts +2 -1
- package/lib/components/features/blog/TMBlogCommentForm.js +5 -5
- package/lib/components/features/documents/TMDcmtBlog.js +1 -1
- package/lib/components/grids/TMBlogs.d.ts +5 -1
- package/lib/components/grids/TMBlogs.js +12 -3
- package/package.json +1 -1
|
@@ -23,10 +23,10 @@ const TMHtmlEditor = (props) => {
|
|
|
23
23
|
setIsPasting(true);
|
|
24
24
|
// Read plain text from the clipboard asynchronously
|
|
25
25
|
let text = await navigator.clipboard.readText();
|
|
26
|
+
// Clean the comment by removing <p> tags and replacing </p> with line breaks
|
|
27
|
+
text = text.replace(/<p>/gi, '').replace(/<\/p>/gi, '\r\n').trim();
|
|
26
28
|
// Removes potentially dangerous HTML tags (script, iframe, embed, etc.) from the pasted content
|
|
27
29
|
text = text.replace(/<(script|iframe|embed|object|link|style|img|video|audio|svg|form|input|button|textarea|select|pre|function)[^>]*>/gi, '');
|
|
28
|
-
// Replace line breaks with HTML paragraph tags to keep formatting
|
|
29
|
-
text = text.replace(/\r\n/g, '</p><p>').replace(/^/, '<p>').replace(/$/, '</p>');
|
|
30
30
|
// Access the Quill editor instance from the HtmlEditor component reference
|
|
31
31
|
const quill = editorRef.current?.instance()?.getQuillInstance();
|
|
32
32
|
if (quill) {
|
|
@@ -5,12 +5,13 @@ interface TMBlogCommentFormProps {
|
|
|
5
5
|
context: TMBlogContextDescriptor;
|
|
6
6
|
participants: Array<UserDescriptor>;
|
|
7
7
|
onClose: () => void;
|
|
8
|
-
refreshCallback: () => void
|
|
8
|
+
refreshCallback: () => Promise<void>;
|
|
9
9
|
showAttachmentsSection?: boolean;
|
|
10
10
|
selectedAttachments?: Array<FileItem>;
|
|
11
11
|
selectedAttachmentDid?: number;
|
|
12
12
|
allFileItems?: FileItem;
|
|
13
13
|
allArchivedDocumentsFileItems?: Array<FileItem>;
|
|
14
|
+
updateShouldSelectLastBlog?: (value: boolean) => void;
|
|
14
15
|
}
|
|
15
16
|
declare const TMBlogCommentForm: (props: TMBlogCommentFormProps) => import("react/jsx-runtime").JSX.Element;
|
|
16
17
|
export default TMBlogCommentForm;
|
|
@@ -28,7 +28,7 @@ const getNonDirectoryFiles = (items, exclude) => {
|
|
|
28
28
|
});
|
|
29
29
|
};
|
|
30
30
|
const TMBlogCommentForm = (props) => {
|
|
31
|
-
const { participants, selectedAttachments, selectedAttachmentDid, allFileItems, allArchivedDocumentsFileItems = [], onClose, refreshCallback, context, showAttachmentsSection = true } = props;
|
|
31
|
+
const { participants, selectedAttachments, selectedAttachmentDid, allFileItems, allArchivedDocumentsFileItems = [], onClose, refreshCallback, context, showAttachmentsSection = true, updateShouldSelectLastBlog } = props;
|
|
32
32
|
// Initialize state with combined array
|
|
33
33
|
const [dataSource, setDataSource] = useState(() => [...getNonDirectoryFiles(allFileItems?.items || [], []), ...allArchivedDocumentsFileItems]);
|
|
34
34
|
const [isEditorEnabled, setIsEditorEnabled] = useState(false);
|
|
@@ -133,8 +133,8 @@ const TMBlogCommentForm = (props) => {
|
|
|
133
133
|
const workingGroupEngine = new WorkingGroupEngine(SDK_Globals.tmSession);
|
|
134
134
|
// Call the BlogPostAddAsync method to add the blog post to the working group
|
|
135
135
|
await workingGroupEngine.BlogPostAddAsync(context.object.id, blogPost)
|
|
136
|
-
.then(() => {
|
|
137
|
-
refreshCallback();
|
|
136
|
+
.then(async () => {
|
|
137
|
+
await refreshCallback().then(() => updateShouldSelectLastBlog?.(true));
|
|
138
138
|
})
|
|
139
139
|
.catch((e) => {
|
|
140
140
|
// If an error occurs, display the exception in an error box
|
|
@@ -150,8 +150,8 @@ const TMBlogCommentForm = (props) => {
|
|
|
150
150
|
// Create an instance of SearchEngine
|
|
151
151
|
const searchEngine = SDK_Globals.tmSession?.NewSearchEngine();
|
|
152
152
|
await searchEngine.BlogPostAddAsync(context.object.tid, context.object.did, cleanComment)
|
|
153
|
-
.then(() => {
|
|
154
|
-
refreshCallback();
|
|
153
|
+
.then(async () => {
|
|
154
|
+
await refreshCallback().then(() => updateShouldSelectLastBlog?.(true));
|
|
155
155
|
})
|
|
156
156
|
.catch((e) => {
|
|
157
157
|
// If an error occurs, display the exception in an error box
|
|
@@ -61,7 +61,7 @@ const TMDcmtBlog = ({ tid, did, isVisible }) => {
|
|
|
61
61
|
isRefreshEnabled: true,
|
|
62
62
|
isRestoreEnabled: true,
|
|
63
63
|
isCreateContextualTask: false
|
|
64
|
-
}, layoutMode: 'chat' }) }) }) }), (showCommentForm && tid && did) && _jsx(TMBlogCommentForm, { context: { engine: 'SearchEngine', object: { tid, did } }, onClose: () => setShowCommentForm(false), refreshCallback: () => { fetchDataAsync(tid, did); }, participants: [], showAttachmentsSection: false })] }));
|
|
64
|
+
}, layoutMode: 'chat' }) }) }) }), (showCommentForm && tid && did) && _jsx(TMBlogCommentForm, { context: { engine: 'SearchEngine', object: { tid, did } }, onClose: () => setShowCommentForm(false), refreshCallback: () => { return fetchDataAsync(tid, did); }, participants: [], showAttachmentsSection: false })] }));
|
|
65
65
|
};
|
|
66
66
|
export default TMDcmtBlog;
|
|
67
67
|
const StyledContainer = styled.div ` user-select: none; overflow: hidden; background-color: #ffffff; width: calc(100%); height: calc(100%); display: flex; gap: 10px; `;
|
|
@@ -70,7 +70,7 @@ interface TMBlogsProps {
|
|
|
70
70
|
isCreateContextualTask: boolean;
|
|
71
71
|
};
|
|
72
72
|
/** Optional refresh callback */
|
|
73
|
-
refreshCallback
|
|
73
|
+
refreshCallback: () => Promise<void>;
|
|
74
74
|
/** An array of partecipants */
|
|
75
75
|
participants?: Array<UserDescriptor>;
|
|
76
76
|
/** An array of new blog posts ID */
|
|
@@ -91,6 +91,10 @@ interface TMBlogsProps {
|
|
|
91
91
|
layoutMode?: 'stacked' | 'chat';
|
|
92
92
|
/** Optional callback to mark blog as read */
|
|
93
93
|
markBlogAsRead?: (blog: BlogPost | undefined) => Promise<void>;
|
|
94
|
+
/** Flag to indicate whether the blog component should automatically select */
|
|
95
|
+
shouldSelectLastBlog?: boolean;
|
|
96
|
+
/** Updates the flag that determines if the blog component should automatically select the last blog. */
|
|
97
|
+
updateShouldSelectLastBlog?: (value: boolean) => void;
|
|
94
98
|
}
|
|
95
99
|
declare const TMBlogs: (props: TMBlogsProps) => import("react/jsx-runtime").JSX.Element;
|
|
96
100
|
export default TMBlogs;
|
|
@@ -30,7 +30,7 @@ const TMBlogs = (props) => {
|
|
|
30
30
|
isRestoreEnabled: false,
|
|
31
31
|
isRefreshEnabled: false,
|
|
32
32
|
isCreateContextualTask: false,
|
|
33
|
-
}, refreshCallback, showCommentFormCallback, showTaskFormCallback, handleAttachmentFocus, showFloatingCommentButton = false, context, layoutMode = 'stacked', markBlogAsRead } = props;
|
|
33
|
+
}, refreshCallback, showCommentFormCallback, showTaskFormCallback, handleAttachmentFocus, showFloatingCommentButton = false, context, layoutMode = 'stacked', markBlogAsRead, shouldSelectLastBlog = false, updateShouldSelectLastBlog } = props;
|
|
34
34
|
// Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
|
|
35
35
|
const deviceType = useDeviceType();
|
|
36
36
|
const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
|
|
@@ -181,9 +181,9 @@ const TMBlogs = (props) => {
|
|
|
181
181
|
if (markBlogAsRead)
|
|
182
182
|
markBlogAsRead(blog);
|
|
183
183
|
};
|
|
184
|
-
const refresh = () => {
|
|
184
|
+
const refresh = async () => {
|
|
185
185
|
if (refreshCallback)
|
|
186
|
-
refreshCallback();
|
|
186
|
+
await refreshCallback();
|
|
187
187
|
};
|
|
188
188
|
const downloadAttachment = () => {
|
|
189
189
|
if (focusedAttachment === undefined)
|
|
@@ -393,6 +393,15 @@ const TMBlogs = (props) => {
|
|
|
393
393
|
if (focusedBlog && focusedBlog.id && filteredBlogs.find(filteredBlog => focusedBlog.id === filteredBlog.id) === undefined)
|
|
394
394
|
handleFocusedBlog(undefined);
|
|
395
395
|
}, [allData, appliedGlobalFilters, searchText, postsToShow, currentHeader]);
|
|
396
|
+
useEffect(() => {
|
|
397
|
+
// Check if we should auto-select the last blog post
|
|
398
|
+
if (shouldSelectLastBlog && updateShouldSelectLastBlog && blogPosts.length > 0) {
|
|
399
|
+
// Reset the flag to prevent re-selecting in future renders
|
|
400
|
+
updateShouldSelectLastBlog(false);
|
|
401
|
+
// Set the focus to the last blog post in the array
|
|
402
|
+
handleFocusedBlog(blogPosts[blogPosts.length - 1]);
|
|
403
|
+
}
|
|
404
|
+
}, [shouldSelectLastBlog, blogPosts]);
|
|
396
405
|
// Scroll the focused blog post into view
|
|
397
406
|
useEffect(() => {
|
|
398
407
|
if (focusedBlog && focusedBlog.id && containerRef.current) {
|