@topconsultnpm/sdkui-react-beta 6.14.89 → 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 +6 -16
- 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/lib/helper/SDKUI_Localizator.d.ts +1 -0
- package/lib/helper/SDKUI_Localizator.js +11 -0
- 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);
|
|
@@ -128,19 +128,13 @@ const TMBlogCommentForm = (props) => {
|
|
|
128
128
|
});
|
|
129
129
|
blogPost.attachments = attachment;
|
|
130
130
|
}
|
|
131
|
-
// Initialize an empty array to hold the result information
|
|
132
|
-
let result = [];
|
|
133
131
|
if (context.engine === 'WorkingGroupEngine' && context.object && context.object.id) {
|
|
134
132
|
// Create an instance of WorkingGroupEngine to interact with the working group
|
|
135
133
|
const workingGroupEngine = new WorkingGroupEngine(SDK_Globals.tmSession);
|
|
136
134
|
// Call the BlogPostAddAsync method to add the blog post to the working group
|
|
137
135
|
await workingGroupEngine.BlogPostAddAsync(context.object.id, blogPost)
|
|
138
|
-
.then(() => {
|
|
139
|
-
|
|
140
|
-
// result.push({ rowIndex: 1, id1: context.object?.id, id2: 0, description: SDKUI_Localizator.UpdateCompletedSuccessfully, resultType: ResultTypes.SUCCESS })
|
|
141
|
-
// Show the result to the user
|
|
142
|
-
// TMResultManager.show(result, SDKUI_Localizator.Comment, "ID", undefined);
|
|
143
|
-
refreshCallback();
|
|
136
|
+
.then(async () => {
|
|
137
|
+
await refreshCallback().then(() => updateShouldSelectLastBlog?.(true));
|
|
144
138
|
})
|
|
145
139
|
.catch((e) => {
|
|
146
140
|
// If an error occurs, display the exception in an error box
|
|
@@ -156,12 +150,8 @@ const TMBlogCommentForm = (props) => {
|
|
|
156
150
|
// Create an instance of SearchEngine
|
|
157
151
|
const searchEngine = SDK_Globals.tmSession?.NewSearchEngine();
|
|
158
152
|
await searchEngine.BlogPostAddAsync(context.object.tid, context.object.did, cleanComment)
|
|
159
|
-
.then(() => {
|
|
160
|
-
|
|
161
|
-
// result.push({ rowIndex: 1, id1: context.object?.tid, id2: context.object?.did, description: SDKUI_Localizator.UpdateCompletedSuccessfully, resultType: ResultTypes.SUCCESS })
|
|
162
|
-
// Show the result to the user
|
|
163
|
-
// TMResultManager.show(result, SDKUI_Localizator.Comment, "ID", undefined);
|
|
164
|
-
refreshCallback();
|
|
153
|
+
.then(async () => {
|
|
154
|
+
await refreshCallback().then(() => updateShouldSelectLastBlog?.(true));
|
|
165
155
|
})
|
|
166
156
|
.catch((e) => {
|
|
167
157
|
// If an error occurs, display the exception in an error box
|
|
@@ -221,7 +211,7 @@ const TMBlogCommentForm = (props) => {
|
|
|
221
211
|
// Update the state with selected draft items
|
|
222
212
|
setCurrentDraftAttachments(selectedDraftItems);
|
|
223
213
|
};
|
|
224
|
-
return _jsx(TMSaveForm, { id: 1, title: SDKUI_Localizator.AddNewComment, showTitleFormMode: false, showErrorCount: false, customSaveButton: _jsx("i", { className: 'dx-icon-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: {
|
|
214
|
+
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: {
|
|
225
215
|
width: 'calc(100% - 60px)',
|
|
226
216
|
overflowX: 'auto',
|
|
227
217
|
whiteSpace: 'nowrap',
|
|
@@ -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,
|
|
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) {
|
|
@@ -380,6 +380,7 @@ export declare class SDKUI_Localizator {
|
|
|
380
380
|
static get Selected(): "Ausgewählt" | "Selected" | "Seleccionados" | "Sélectionné" | "Selecionado" | "Selezionati";
|
|
381
381
|
static get SelectDesiredFilters(): "Wählen Sie die gewünschten Filter aus" | "Select the desired filters" | "Selecciona los filtros deseados" | "Sélectionnez les filtres souhaités" | "Selecione os filtros desejados" | "Seleziona i filtri desiderati";
|
|
382
382
|
static get SelectedItems(): "Ausgewählte Artikel" | "Selected items" | "Artículos seleccionados" | "Articles sélectionnés" | "Itens selecionados" | "Elementi selezionati";
|
|
383
|
+
static get Send(): "Senden" | "Send" | "Enviar" | "Envoyer" | "Invia";
|
|
383
384
|
static get SendLinkByMail(): "Link per E-Mail senden" | "Send link via mail" | "Enviar enlace por correo electrónico" | "Envoyer le lien par email" | "Enviar link por e-mail" | "Invia link tramite mail";
|
|
384
385
|
static get SendToSupport(): "An den Support senden" | "Send to support" | "Enviar a soporte" | "Envoyer au support" | "Enviar para suporte" | "Invia a supporto";
|
|
385
386
|
static get SetAsDefault(): "Als Standardbaum festlegen" | "Set as default" | "Establecer como predeterminado" | "Définir par défaut" | "Definir como padrão" | "Imposta come predefinito";
|
|
@@ -3758,6 +3758,17 @@ export class SDKUI_Localizator {
|
|
|
3758
3758
|
default: return "Elementi selezionati";
|
|
3759
3759
|
}
|
|
3760
3760
|
}
|
|
3761
|
+
static get Send() {
|
|
3762
|
+
switch (this._cultureID) {
|
|
3763
|
+
case CultureIDs.De_DE: return "Senden";
|
|
3764
|
+
case CultureIDs.En_US: return "Send";
|
|
3765
|
+
case CultureIDs.Es_ES: return "Enviar";
|
|
3766
|
+
case CultureIDs.Fr_FR: return "Envoyer";
|
|
3767
|
+
case CultureIDs.Pt_PT: return "Enviar";
|
|
3768
|
+
case CultureIDs.It_IT: return "Invia";
|
|
3769
|
+
default: return "Send";
|
|
3770
|
+
}
|
|
3771
|
+
}
|
|
3761
3772
|
static get SendLinkByMail() {
|
|
3762
3773
|
switch (this._cultureID) {
|
|
3763
3774
|
case CultureIDs.De_DE: return "Link per E-Mail senden";
|