@topconsultnpm/sdkui-react 6.19.0-dev1.51 → 6.19.0-dev1.52

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.
@@ -1,8 +1,6 @@
1
- import React from 'react';
1
+ import { ReactNode } from "react";
2
2
  import { BlogPost, BlogPostAttachment, DcmtTypeDescriptor, DossierDescriptor, HomeBlogPost, TID_DID, WorkingGroupDescriptor } from "@topconsultnpm/sdk-ts";
3
- import { DcmtInfo } from '../../ts';
4
- import { ContextMenuRef } from 'devextreme-react/cjs/context-menu';
5
- import { FileItem } from '../base/TMFileManagerUtils';
3
+ import { FileItem } from "../base/TMFileManagerUtils";
6
4
  export declare const DRAFT_TYPE_TID = 6;
7
5
  export type TMBlogContextDescriptor = {
8
6
  engine: 'WorkingGroupEngine';
@@ -14,15 +12,28 @@ export type TMBlogContextDescriptor = {
14
12
  engine: 'DossierEngine';
15
13
  object?: DossierDescriptor;
16
14
  };
17
- export declare const colors: {
18
- DARK_BLUE: string;
19
- WHITE: string;
20
- BLACK: string;
21
- RED: string;
22
- LIGHT_GRAY: string;
23
- PRIMARY_BLUE: string;
24
- PRIMARY_ORANGE: string;
25
- PRIMARY_GREEN: string;
15
+ export declare enum TMBlogsFilterCategoryId {
16
+ PublishedBlogs = 1,
17
+ SystemBlogs = 2,
18
+ DeletedBlogs = 3
19
+ }
20
+ export type TMBlogsFilterCategoryIdDataSource = {
21
+ id: number;
22
+ label: string;
23
+ value: string;
24
+ categoryId?: number;
25
+ expanded?: boolean;
26
+ tooltipContent?: ReactNode;
27
+ };
28
+ export type TMBlogsPostHeader = {
29
+ /** Flag to display the view mode toggle */
30
+ showViewMode: boolean;
31
+ /** Flag to display filter options */
32
+ showFilters: boolean;
33
+ /** Flag to display the search bar */
34
+ showSearchBar: boolean;
35
+ /** Flag to display a dropdown menu for selecting posts */
36
+ showPostsDropDown: boolean;
26
37
  };
27
38
  export interface TMBlogContextMenuItem {
28
39
  text: string;
@@ -36,26 +47,22 @@ export interface TMBlogContextMenuItem {
36
47
  tooltip?: string;
37
48
  visible?: boolean;
38
49
  }
39
- export declare enum TMBlogsFilterCategoryId {
40
- PublishedBlogs = 1,
41
- SystemBlogs = 2,
42
- DeletedBlogs = 3
43
- }
44
- export interface BlogPostContainerProps {
45
- $color?: string;
46
- $textDecoration?: string;
47
- $backgroundColor?: string;
48
- $canNavigate?: boolean;
49
- $paddingTop?: string;
50
- $paddingRight?: string;
51
- $paddingBottom?: string;
52
- $paddingLeft?: string;
53
- }
54
- export declare const BlogPostContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, BlogPostContainerProps>> & string;
55
- export declare const getTooltipContent: (title: string | undefined, content: JSX.Element) => import("react/jsx-runtime").JSX.Element;
50
+ export declare const getCompactEllipsisStyle: (layoutMode: "compact" | "extended") => {
51
+ whiteSpace?: undefined;
52
+ overflow?: undefined;
53
+ textOverflow?: undefined;
54
+ display?: undefined;
55
+ } | {
56
+ whiteSpace: string;
57
+ overflow: string;
58
+ textOverflow: string;
59
+ display: string;
60
+ };
61
+ export declare const findFileItemByDraftID: (tree: FileItem | undefined, draftID: number | undefined) => FileItem | null;
56
62
  export declare const highlightText: (text: string, searchText: string, isSelected: boolean) => string | (string | import("react/jsx-runtime").JSX.Element)[];
57
63
  export declare const lightenColor: (hex: string, amount: number) => string;
58
- export declare const removeFileExtension: (filename: string) => string;
64
+ export declare const OwnerInitialsBadge: (blogPost: BlogPost | HomeBlogPost) => import("react/jsx-runtime").JSX.Element;
65
+ export declare const getTooltipContent: (title: string | undefined, content: JSX.Element) => import("react/jsx-runtime").JSX.Element;
59
66
  export declare const getAttachmentInfo: (attachment: BlogPostAttachment, treeFs: FileItem | undefined, draftLatestInfoMap: Map<number, {
60
67
  latestVersion: number;
61
68
  folderId: number;
@@ -67,7 +74,7 @@ export declare const getAttachmentInfo: (attachment: BlogPostAttachment, treeFs:
67
74
  did: number;
68
75
  fileExt: string;
69
76
  fileSize: string;
70
- }> | undefined, dcmtTypeDescriptors: Map<number, DcmtTypeDescriptor>, isSelected: boolean, searchText: string, color: string) => {
77
+ }> | undefined, dcmtTypeDescriptors: Map<number, DcmtTypeDescriptor>, isSelected: boolean, searchText: string) => {
71
78
  name: string;
72
79
  nameElement: import("react/jsx-runtime").JSX.Element;
73
80
  tooltipContent: import("react/jsx-runtime").JSX.Element;
@@ -76,25 +83,31 @@ export declare const getAttachmentInfo: (attachment: BlogPostAttachment, treeFs:
76
83
  draftExist: boolean;
77
84
  archivedDocumentsExist: boolean;
78
85
  };
79
- export declare const findFileItemByTidDid: (tree: FileItem | undefined, tid: number | undefined, did: number | undefined) => FileItem | null;
80
- export declare const AttachmentElement: (attachment: BlogPostAttachment, treeFs: FileItem | undefined, draftLatestInfoMap: Map<number, {
81
- latestVersion: number;
82
- folderId: number;
83
- folderName: string;
84
- fileExt: string;
85
- fileSize: string;
86
- }> | undefined, archivedDocumentMap: Map<number, {
87
- tid: number;
88
- did: number;
89
- fileExt: string;
90
- fileSize: string;
91
- }> | undefined, dcmtTypeDescriptors: Map<number, DcmtTypeDescriptor>, isSelected: boolean, searchText: string, color: string, setShowDcmtForm: React.Dispatch<React.SetStateAction<boolean>>, handleFocusedAttachment: (attachment: DcmtInfo | undefined) => void, setAnchorEl: (value: React.SetStateAction<HTMLElement | null>) => void, contextMenuRef: React.MutableRefObject<ContextMenuRef<any> | null>) => import("react/jsx-runtime").JSX.Element;
92
- export declare const OwnerInitialsBadge: (blogPost: BlogPost | HomeBlogPost) => import("react/jsx-runtime").JSX.Element;
93
- export declare const IconAndHeaderElement: (blogPost: BlogPost | HomeBlogPost, iconColor: string, isSelected: boolean, headerClickCallback: () => void, searchText: string) => import("react/jsx-runtime").JSX.Element;
94
- export declare const findFileItemByDraftID: (tree: FileItem | undefined, draftID: number | undefined) => FileItem | null;
86
+ export declare const getDcmtTypeDescriptor: (blogPosts: Array<BlogPost>) => Promise<Map<number, DcmtTypeDescriptor>>;
87
+ export declare const BlogPostHomeHeader: (header: string | undefined, classId: string | undefined, isSelected: boolean, searchText: string, headerClickCallback: () => void) => import("react/jsx-runtime").JSX.Element;
95
88
  export declare const isHeaderFullyHidden: (header: {
96
89
  showViewMode: boolean;
97
90
  showFilters: boolean;
98
91
  showSearchBar: boolean;
99
92
  showPostsDropDown: boolean;
100
93
  } | undefined) => boolean;
94
+ interface NewBadgeProps {
95
+ layoutMode: "compact" | "extended";
96
+ }
97
+ export declare const NewBadge: ({ layoutMode }: NewBadgeProps) => import("react/jsx-runtime").JSX.Element;
98
+ export declare const removeFileExtension: (filename: string) => string;
99
+ interface BlogPostTitleProps {
100
+ displayMode: "chat" | "stacked";
101
+ layoutMode: "compact" | "extended";
102
+ blogPost: BlogPost | HomeBlogPost;
103
+ isSelected: boolean;
104
+ isOwnComment: boolean;
105
+ searchText: string;
106
+ isSys: boolean;
107
+ isHomeBlogPost: boolean;
108
+ showId: boolean;
109
+ handleNavigateToWGs?: (blogPost: BlogPost | HomeBlogPost) => void;
110
+ handleNavigateToDossiers?: (blogPost: BlogPost | HomeBlogPost) => void;
111
+ }
112
+ export declare const BlogPostTitle: (props: BlogPostTitleProps) => import("react/jsx-runtime").JSX.Element;
113
+ export {};
@@ -1,60 +1,48 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import styled from "styled-components";
3
- import { SDK_Globals, SystemTIDs } from "@topconsultnpm/sdk-ts";
4
- import { extractInitialsFromName, formatBytes, getAvatarColor, IconAttachment, IconCADossier, IconMenuCAWorkingGroups, SDKUI_Localizator } from "../../helper";
2
+ import { DcmtTypeListCacheService } from "@topconsultnpm/sdk-ts";
3
+ import { getAvatarColor, extractInitialsFromName, SDKUI_Localizator, formatBytes, IconMenuCAWorkingGroups, IconCADossier, Globalization } from "../../helper";
4
+ import { TMColors } from "../../utils/theme";
5
5
  import TMTooltip from "../base/TMTooltip";
6
- import { TMColors } from '../../utils/theme';
7
- import TMDcmtIcon from '../features/documents/TMDcmtIcon';
8
6
  export const DRAFT_TYPE_TID = 6;
9
- export const colors = {
10
- DARK_BLUE: "#1a0dab",
11
- WHITE: "#fff",
12
- BLACK: "#000000",
13
- RED: '#ff0000',
14
- LIGHT_GRAY: "#f9f9f9",
15
- PRIMARY_BLUE: "#135596",
16
- PRIMARY_ORANGE: "#e65b00",
17
- PRIMARY_GREEN: "#009700"
18
- };
19
7
  export var TMBlogsFilterCategoryId;
20
8
  (function (TMBlogsFilterCategoryId) {
21
9
  TMBlogsFilterCategoryId[TMBlogsFilterCategoryId["PublishedBlogs"] = 1] = "PublishedBlogs";
22
10
  TMBlogsFilterCategoryId[TMBlogsFilterCategoryId["SystemBlogs"] = 2] = "SystemBlogs";
23
11
  TMBlogsFilterCategoryId[TMBlogsFilterCategoryId["DeletedBlogs"] = 3] = "DeletedBlogs";
24
12
  })(TMBlogsFilterCategoryId || (TMBlogsFilterCategoryId = {}));
25
- export const BlogPostContainer = styled.div `
26
- color: ${(props) => (props.$color ?? colors.BLACK)};
27
- text-decoration: ${(props) => (props.$textDecoration ?? 'none')};
28
- height: auto;
29
- background-color: ${(props) => (props.$backgroundColor ?? colors.WHITE)};
30
- display: inline-block;
31
- width: 100%;
32
- min-width: 100px;
33
- max-width: 100%;
34
- cursor: ${(props) => (props.$canNavigate ? "pointer" : "default")};
35
- border-radius: 5px;
36
- margin: 5px 0;
37
- padding: ${(props) => `${props.$paddingTop ?? '10px'} ${props.$paddingRight ?? '10px'} ${props.$paddingBottom ?? '10px'} ${props.$paddingLeft ?? '10px'}`};
38
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
39
- word-wrap: break-word;
40
- white-space: pre-wrap;
41
- &:hover {
42
- box-shadow: 0 4px 12px rgba(19, 85, 150, 0.6);
43
- transition:
44
- box-shadow 0.3s ease,
45
- transform 0.3s ease;
46
- };
47
- &:focus {
48
- outline: none;
49
- }
50
- `;
51
- export const getTooltipContent = (title, content) => {
52
- return (_jsxs("div", { style: { textAlign: 'left' }, children: [_jsx("div", { style: { fontWeight: 'bold' }, children: title }), _jsx("hr", {}), content] }));
13
+ export const getCompactEllipsisStyle = (layoutMode) => {
14
+ if (layoutMode !== "compact")
15
+ return {};
16
+ return {
17
+ whiteSpace: "nowrap",
18
+ overflow: "hidden",
19
+ textOverflow: "ellipsis",
20
+ display: "block",
21
+ };
22
+ };
23
+ export const findFileItemByDraftID = (tree, draftID) => {
24
+ if (tree === undefined || draftID === undefined)
25
+ return null;
26
+ if (tree.id === draftID) {
27
+ return tree;
28
+ }
29
+ if (tree.items && tree.items.length > 0) {
30
+ for (const item of tree.items) {
31
+ const found = findFileItemByDraftID(item, draftID);
32
+ if (found) {
33
+ return found;
34
+ }
35
+ }
36
+ }
37
+ return null;
53
38
  };
54
39
  export const highlightText = (text, searchText, isSelected) => {
55
40
  if (!searchText)
56
41
  return text;
57
- const regex = new RegExp(`(${searchText.trim()})`, 'gi');
42
+ if (searchText.trim() === '')
43
+ return text;
44
+ const escapedSearchText = searchText.trim().replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
45
+ const regex = new RegExp(`(${escapedSearchText})`, 'gi');
58
46
  return text.split(regex).map((part, index) => regex.test(part) ? (_jsx("span", { style: { backgroundColor: isSelected ? '#6c9023' : 'yellow' }, children: part }, index)) : (part));
59
47
  };
60
48
  export const lightenColor = (hex, amount) => {
@@ -72,10 +60,25 @@ export const lightenColor = (hex, amount) => {
72
60
  b = Math.min(255, Math.max(0, b));
73
61
  return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, '0')}`;
74
62
  };
75
- export const removeFileExtension = (filename) => {
76
- return filename.includes('.') ? filename.substring(0, filename.lastIndexOf('.')) : filename;
63
+ export const OwnerInitialsBadge = (blogPost) => {
64
+ return _jsx(TMTooltip, { content: blogPost.ownerName ?? '-', children: _jsx("div", { style: {
65
+ width: "40px",
66
+ height: "40px",
67
+ borderRadius: "50%",
68
+ backgroundColor: getAvatarColor(blogPost.ownerName ?? '-'),
69
+ display: "flex",
70
+ alignItems: "center",
71
+ justifyContent: "center",
72
+ marginRight: "10px",
73
+ fontWeight: "bold",
74
+ color: "#ffffff",
75
+ fontSize: "18px",
76
+ }, children: _jsx("span", { style: { fontSize: "12px" }, children: extractInitialsFromName(blogPost.ownerName ?? '-') }) }) });
77
+ };
78
+ export const getTooltipContent = (title, content) => {
79
+ return (_jsxs("div", { style: { textAlign: 'left' }, children: [_jsx("div", { style: { fontWeight: 'bold' }, children: title }), _jsx("hr", {}), content] }));
77
80
  };
78
- export const getAttachmentInfo = (attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText, color) => {
81
+ export const getAttachmentInfo = (attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText) => {
79
82
  let nameElement = (_jsx("span", { children: `${SDKUI_Localizator.DocumentNotAvailable} (DID: ${attachment.did})` }));
80
83
  let folderId = -1;
81
84
  let fileExt = '';
@@ -111,7 +114,7 @@ export const getAttachmentInfo = (attachment, treeFs, draftLatestInfoMap, archiv
111
114
  alignItems: 'center',
112
115
  justifyContent: 'center',
113
116
  backgroundColor: isSelected ? '#fff' : (latestVersion ? '#28a745' : '#cc7000'),
114
- color: isSelected ? color : '#fff',
117
+ color: isSelected ? "#135596" : '#fff',
115
118
  boxShadow: '1px 1px 2px #00000020',
116
119
  borderRadius: '30px',
117
120
  fontWeight: 'bold',
@@ -130,129 +133,45 @@ export const getAttachmentInfo = (attachment, treeFs, draftLatestInfoMap, archiv
130
133
  }
131
134
  }
132
135
  if (descriptor) {
133
- // Default name from descriptor
134
136
  name = descriptor.name ?? "-";
135
- // If descriptor is DSAttachs, try to find the actual archived file in treeFs by tid/did
136
- if (descriptor.id === SystemTIDs.DSAttachs && treeFs && attachment.tid && attachment.did) {
137
- const found = findFileItemByTidDid(treeFs, attachment.tid, attachment.did);
138
- if (found) {
139
- name = found.name ?? name;
140
- fileExt = found.ext ?? (found.name && found.name.includes('.') ? found.name.substring(found.name.lastIndexOf('.') + 1) : fileExt);
141
- archivedDocumentsExist = true;
142
- }
143
- }
144
137
  const content = (_jsxs("div", { children: [archivedDocumentMap && (_jsxs("div", { children: [_jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.Size }), ": ", fileSize] })), _jsx("hr", {}), _jsxs("div", { children: [_jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.Path }), ": \"", SDKUI_Localizator.ArchivedDocuments, "\\", `${descriptor.name} (DID: ${attachment.did})`, "\""] })] }));
145
138
  tooltipContent = getTooltipContent(descriptor.name, content);
146
- nameElement = (_jsx("span", { children: descriptor.id !== SystemTIDs.DSAttachs
147
- ? highlightText(`${name} (DID: ${attachment.did})`, searchText, isSelected)
148
- : highlightText(`${name}`, searchText, isSelected) }));
139
+ nameElement = (_jsx("span", { children: highlightText(`${name} (DID: ${attachment.did})`, searchText, isSelected) }));
149
140
  }
150
141
  }
151
142
  return { name, nameElement, tooltipContent, folderId, fileExt, draftExist, archivedDocumentsExist };
152
143
  };
153
- // Helper: find a file item by tid and did inside the treeFs structure
154
- export const findFileItemByTidDid = (tree, tid, did) => {
155
- if (!tree || tid === undefined || did === undefined)
156
- return null;
157
- const stack = [tree];
158
- while (stack.length > 0) {
159
- const node = stack.pop();
160
- if (!node)
161
- continue;
162
- if (!node.isDirectory) {
163
- if ((node.tid === tid || node.tid === Number(tid)) && (node.did === did || node.did === Number(did))) {
164
- return node;
165
- }
166
- }
167
- if (node.items && node.items.length > 0) {
168
- for (const child of node.items) {
169
- stack.push(child);
144
+ export const getDcmtTypeDescriptor = async (blogPosts) => {
145
+ // Create a Map to store tid as key and DcmtTypeDescriptor as value
146
+ const dcmtTypeMap = new Map();
147
+ for (const blogPost of blogPosts) {
148
+ if (blogPost.attachments) {
149
+ for (const attachment of blogPost.attachments) {
150
+ const dcmtTypeDescriptor = await DcmtTypeListCacheService.GetAsync(attachment.tid, true);
151
+ if (dcmtTypeDescriptor && attachment.tid) {
152
+ dcmtTypeMap.set(attachment.tid, dcmtTypeDescriptor);
153
+ }
170
154
  }
171
155
  }
172
156
  }
173
- return null;
157
+ return dcmtTypeMap;
174
158
  };
175
- export const AttachmentElement = (attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText, color, setShowDcmtForm, handleFocusedAttachment, setAnchorEl, contextMenuRef) => {
176
- const { name, nameElement, tooltipContent, fileExt, archivedDocumentsExist, draftExist } = getAttachmentInfo(attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText, color);
177
- const onDoubleClick = (e) => {
178
- e.preventDefault();
179
- e.stopPropagation();
180
- const archiveID = SDK_Globals.tmSession?.SessionDescr?.archiveID;
181
- const fileName = `${removeFileExtension(name)}_${archiveID}_${attachment.tid}_${attachment.did}.${fileExt}`;
182
- handleFocusedAttachment({ TID: attachment.tid, DID: attachment.did, fileName });
183
- setShowDcmtForm(true);
184
- };
185
- const onContextMenu = (e) => {
186
- const archiveID = SDK_Globals.tmSession?.SessionDescr?.archiveID;
187
- const fileName = `${removeFileExtension(name)}_${archiveID}_${attachment.tid}_${attachment.did}.${fileExt}`;
188
- handleFocusedAttachment({ TID: attachment.tid, DID: attachment.did, fileName });
189
- setAnchorEl(e.currentTarget);
190
- e.preventDefault();
191
- e.stopPropagation();
192
- // Slight delay to ensure state update before showing context menu
193
- setTimeout(() => {
194
- contextMenuRef.current?.instance()?.show();
195
- }, 0);
196
- };
197
- return _jsx("div", { onDoubleClick: onDoubleClick, onContextMenu: onContextMenu, style: {
198
- display: 'inline-flex',
199
- padding: '4px 8px',
200
- margin: '4px',
201
- border: '1px solid #ddd',
202
- borderRadius: '8px',
203
- boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
204
- backgroundColor: isSelected ? color : colors.WHITE,
159
+ export const BlogPostHomeHeader = (header, classId, isSelected, searchText, headerClickCallback) => {
160
+ const isWorkGroup = classId === 'WG';
161
+ const iconColor = isSelected ? '#ffffff' : isWorkGroup ? '#009700' : '#e65b00';
162
+ return (_jsxs("div", { onClick: headerClickCallback, style: {
163
+ display: "flex",
164
+ alignItems: "center",
205
165
  cursor: "pointer",
206
- fontSize: '0.9rem'
207
- }, onMouseEnter: (e) => {
208
- e.currentTarget.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.15)';
209
- e.currentTarget.style.backgroundColor = isSelected ? lightenColor(color, 40) : '#cfcfcf';
210
- }, onMouseLeave: (e) => {
211
- e.currentTarget.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
212
- e.currentTarget.style.backgroundColor = isSelected ? color : colors.WHITE;
213
- }, children: _jsxs("div", { style: { alignItems: 'center', display: 'flex' }, children: [(!archivedDocumentsExist && !draftExist) ?
214
- _jsx(IconAttachment, { style: { marginRight: "5px" } }) :
215
- _jsx("div", { style: { marginRight: "10px" }, children: _jsx(TMDcmtIcon, { tid: attachment.tid, did: attachment.did, fileExtension: fileExt, downloadMode: 'openInNewWindow', tooltipContent: tooltipContent }) }), _jsx("span", { children: nameElement })] }) }, attachment.did);
216
- };
217
- export const OwnerInitialsBadge = (blogPost) => {
218
- return _jsx(TMTooltip, { content: blogPost.ownerName ?? '-', children: _jsx("div", { style: {
219
- width: "40px",
220
- height: "40px",
221
- borderRadius: "50%",
222
- backgroundColor: getAvatarColor(blogPost.ownerName ?? '-'),
223
- display: "flex",
224
- alignItems: "center",
225
- justifyContent: "center",
226
- marginRight: "10px",
227
- fontWeight: "bold",
228
- color: colors.WHITE,
229
- fontSize: "18px",
230
- }, children: _jsx("span", { style: { fontSize: "12px" }, children: extractInitialsFromName(blogPost.ownerName ?? '-') }) }) });
231
- };
232
- export const IconAndHeaderElement = (blogPost, iconColor, isSelected, headerClickCallback, searchText) => {
233
- return _jsxs("span", { style: { marginLeft: "5px", cursor: blogPost.classID === 'WG' ? "pointer" : "default", display: "inline-flex", alignItems: "center" }, onClick: headerClickCallback, children: [_jsx(TMTooltip, { content: blogPost.classID === 'DS' ? SDKUI_Localizator.Practice : SDKUI_Localizator.WorkGroup, children: blogPost.classID === "DS" ? (_jsx(IconCADossier, { color: iconColor, fontSize: 28 })) : (_jsx(IconMenuCAWorkingGroups, { color: iconColor, fontSize: 28 })) }), _jsx("span", { style: {
234
- marginLeft: "5px",
235
- // textDecoration: (blogPost as HomeBlogPost).classID === "WG" ? "underline" : "none",
236
- cursor: blogPost.classID === "WG" ? "pointer" : "default",
237
- color: isSelected ? "#fff" : TMColors.primary,
238
- display: "inline-block" // Ensure both elements are in a row
239
- }, onClick: headerClickCallback, children: highlightText(blogPost.header ?? '', searchText, isSelected) })] });
240
- };
241
- export const findFileItemByDraftID = (tree, draftID) => {
242
- if (tree === undefined || draftID === undefined)
243
- return null;
244
- if (tree.id === draftID) {
245
- return tree;
246
- }
247
- if (tree.items && tree.items.length > 0) {
248
- for (const item of tree.items) {
249
- const found = findFileItemByDraftID(item, draftID);
250
- if (found) {
251
- return found;
252
- }
253
- }
254
- }
255
- return null;
166
+ fontWeight: "bold",
167
+ color: isSelected ? "#fff" : TMColors.primary,
168
+ gap: "4px",
169
+ }, children: [_jsx(TMTooltip, { content: isWorkGroup ? SDKUI_Localizator.WorkGroup : SDKUI_Localizator.Practice, children: isWorkGroup ? (_jsx(IconMenuCAWorkingGroups, { color: iconColor, fontSize: 28 })) : (_jsx(IconCADossier, { color: iconColor, fontSize: 28 })) }), _jsx("div", { style: {
170
+ whiteSpace: "nowrap",
171
+ overflow: "hidden",
172
+ textOverflow: "ellipsis",
173
+ flex: 1,
174
+ }, children: highlightText(header ?? "", searchText, isSelected) })] }));
256
175
  };
257
176
  export const isHeaderFullyHidden = (header) => {
258
177
  if (!header) {
@@ -260,3 +179,67 @@ export const isHeaderFullyHidden = (header) => {
260
179
  }
261
180
  return !header.showViewMode && !header.showFilters && !header.showSearchBar && !header.showPostsDropDown;
262
181
  };
182
+ export const NewBadge = ({ layoutMode }) => {
183
+ const isCompact = layoutMode === "compact";
184
+ return (_jsxs("div", { style: {
185
+ position: "absolute",
186
+ top: isCompact ? "6px" : "8px",
187
+ right: isCompact ? "6px" : "8px",
188
+ background: "linear-gradient(270deg, #FFD76A 0%, #FFC940 50%, #FFB800 100%)",
189
+ color: TMColors.primary,
190
+ fontSize: isCompact ? "0" : "0.65rem",
191
+ fontWeight: "700",
192
+ letterSpacing: "0.5px",
193
+ padding: isCompact ? "0" : "3px 8px",
194
+ borderRadius: isCompact ? "50%" : "12px",
195
+ width: isCompact ? "10px" : "auto",
196
+ height: isCompact ? "10px" : "auto",
197
+ display: "flex",
198
+ alignItems: "center",
199
+ justifyContent: "center",
200
+ boxShadow: "0 2px 10px rgba(255, 200, 50, 0.45)",
201
+ zIndex: 1,
202
+ animation: "softBlink 2s infinite",
203
+ }, title: SDKUI_Localizator.New, children: [!isCompact && "NEW", _jsx("style", { children: `
204
+ @keyframes softBlink {
205
+ 0%, 100% { opacity: 1; }
206
+ 50% { opacity: 0.7; }
207
+ }
208
+ ` })] }));
209
+ };
210
+ export const removeFileExtension = (filename) => {
211
+ return filename.includes('.') ? filename.substring(0, filename.lastIndexOf('.')) : filename;
212
+ };
213
+ export const BlogPostTitle = (props) => {
214
+ const { displayMode, layoutMode, blogPost, isSelected, isOwnComment, searchText, isSys, isHomeBlogPost, showId, handleNavigateToWGs, handleNavigateToDossiers } = props;
215
+ const showOwnerBadge = (displayMode === "stacked" || !isOwnComment) && layoutMode === "extended";
216
+ let subtitle = "";
217
+ if (isHomeBlogPost) {
218
+ subtitle = blogPost.ownerName ? `${blogPost.ownerName} \u2014 ` : "";
219
+ }
220
+ if (blogPost.creationTime) {
221
+ subtitle += `${Globalization.getDateTimeDisplayValue(blogPost.creationTime)} ${new Date(blogPost.creationTime).toDateString() === new Date().toDateString()
222
+ ? `(${SDKUI_Localizator.Today})`
223
+ : ''}`;
224
+ }
225
+ if (showId && blogPost.id !== undefined) {
226
+ subtitle += ` \u2014 ID: ${blogPost.id}`;
227
+ }
228
+ const headerClickCallback = () => {
229
+ if (handleNavigateToWGs && blogPost.id && blogPost.classID === 'WG') {
230
+ handleNavigateToWGs(blogPost);
231
+ }
232
+ if (handleNavigateToDossiers && blogPost.id && blogPost.classID === 'DS') {
233
+ handleNavigateToDossiers(blogPost);
234
+ }
235
+ };
236
+ return _jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [showOwnerBadge && (_jsx("div", { style: { width: "40px", height: "40px", flexShrink: 0 }, children: OwnerInitialsBadge(blogPost) })), _jsxs("div", { style: {
237
+ display: "flex",
238
+ flexDirection: "column",
239
+ width: showOwnerBadge ? "calc(100% - 40px)" : "100%",
240
+ }, children: [(isHomeBlogPost && blogPost.classID) && BlogPostHomeHeader(blogPost.header, blogPost.classID, isSelected, searchText, headerClickCallback), (!isHomeBlogPost && !isOwnComment && blogPost.ownerName && blogPost.ownerName.trim().length > 0) && (_jsx("span", { style: {
241
+ fontWeight: "bold",
242
+ color: isSelected ? "#fff" : !isSys ? TMColors.primary : "#ff0000",
243
+ ...getCompactEllipsisStyle(layoutMode),
244
+ }, children: highlightText(blogPost.ownerName, searchText, isSelected) })), subtitle.length > 0 && (_jsx("div", { style: { ...getCompactEllipsisStyle(layoutMode) }, children: highlightText(subtitle, searchText, isSelected) }))] })] });
245
+ };
@@ -53,7 +53,9 @@ export * from './choosers/TMOrderRetrieveFormats';
53
53
  export * from './choosers/TMUserChooser';
54
54
  export * from './choosers/TMPathChooser';
55
55
  export { default as TMValidationItemsList } from './grids/TMValidationItemsList';
56
- export { default as TMBlogs } from './grids/TMBlogs';
56
+ export { default as TMBlogsPost } from './grids/TMBlogsPost';
57
+ export { default as TMBlogHeader } from './grids/TMBlogHeader';
58
+ export { default as TMBlogAttachments } from './grids/TMBlogAttachments';
57
59
  export { default as TMBlogCommentForm } from './features/blog/TMBlogCommentForm';
58
60
  export * from './query/TMQueryEditor';
59
61
  export * from './query/TMQuerySummary';
@@ -58,7 +58,9 @@ export * from './choosers/TMPathChooser';
58
58
  //grids
59
59
  export { default as TMValidationItemsList } from './grids/TMValidationItemsList';
60
60
  // blogs
61
- export { default as TMBlogs } from './grids/TMBlogs';
61
+ export { default as TMBlogsPost } from './grids/TMBlogsPost';
62
+ export { default as TMBlogHeader } from './grids/TMBlogHeader';
63
+ export { default as TMBlogAttachments } from './grids/TMBlogAttachments';
62
64
  export { default as TMBlogCommentForm } from './features/blog/TMBlogCommentForm';
63
65
  //query
64
66
  export * from './query/TMQueryEditor';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react",
3
- "version": "6.19.0-dev1.51",
3
+ "version": "6.19.0-dev1.52",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",