@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.
@@ -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
- // On success, push a success result to the result array
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
- // On success, push a success result to the result array
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?: () => void;
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, newPosts = [], showCommentFormCallback, showTaskFormCallback, showContextMenu = true, 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) {
@@ -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";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.14.89",
3
+ "version": "6.14.91",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",