@topconsultnpm/sdkui-react-beta 6.15.73 → 6.15.75

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.
@@ -30,6 +30,8 @@ interface ITMSearchResultProps {
30
30
  openWGsCopyMoveForm?: (mode: "copyToWgDraft" | "copyToWgArchivedDoc", dcmtTypeDescriptor: DcmtTypeDescriptor, documents: Array<DcmtInfo>) => void;
31
31
  openCommentFormCallback?: (documents: Array<DcmtInfo>) => void;
32
32
  openAddDocumentForm?: () => void;
33
+ openS4TViewer?: boolean;
34
+ onOpenS4TViewerRequest?: (dcmtInfo: Array<DcmtInfo>) => void;
33
35
  }
34
36
  declare const TMSearchResult: React.FC<ITMSearchResultProps>;
35
37
  export default TMSearchResult;
@@ -32,7 +32,6 @@ import TMDcmtBlog from '../documents/TMDcmtBlog';
32
32
  import TMDcmtIcon from '../documents/TMDcmtIcon';
33
33
  import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/panelManager/TMPanelManagerContext';
34
34
  import TMPanelManagerContainer from '../../layout/panelManager/TMPanelManagerContainer';
35
- import ShowAlert from '../../base/TMAlert';
36
35
  import ToppyHelpCenter from '../assistant/ToppyHelpCenter';
37
36
  import TMAccordion from '../../base/TMAccordion';
38
37
  import TMDataGridExportForm from '../../base/TMDataGridExportForm';
@@ -54,7 +53,7 @@ const orderByName = (array) => {
54
53
  return 1;
55
54
  } return 0; });
56
55
  };
57
- const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisible = true, allowRelations = true, openDcmtFormAsModal = false, searchResults = [], showSearchResultSidebar = true, showSelector = false, groupId, title, isClosable = false, allowFloatingBar = true, showToolbarHeader = true, selectedSearchResultTID, workingGroupContext = undefined, disableAccordionIfSingleCategory = false, floatingActionConfig, onRefreshAfterAddDcmtToFavs, onRefreshSearchAsync, onSelectedTIDChanged, onWFOperationCompleted, onClose, onFileOpened, onTaskCreateRequest, openWGsCopyMoveForm, openCommentFormCallback, openAddDocumentForm }) => {
56
+ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisible = true, allowRelations = true, openDcmtFormAsModal = false, searchResults = [], showSearchResultSidebar = true, showSelector = false, groupId, title, isClosable = false, allowFloatingBar = true, showToolbarHeader = true, selectedSearchResultTID, workingGroupContext = undefined, disableAccordionIfSingleCategory = false, floatingActionConfig, onRefreshAfterAddDcmtToFavs, onRefreshSearchAsync, onSelectedTIDChanged, onWFOperationCompleted, onClose, onFileOpened, onTaskCreateRequest, openWGsCopyMoveForm, openCommentFormCallback, openAddDocumentForm, openS4TViewer = false, onOpenS4TViewerRequest }) => {
58
57
  const [id, setID] = useState('');
59
58
  const [showApprovePopup, setShowApprovePopup] = useState(false);
60
59
  const [showRejectPopup, setShowRejectPopup] = useState(false);
@@ -87,9 +86,13 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
87
86
  const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, runOperationAsync } = useDcmtOperations();
88
87
  const deviceType = useDeviceType();
89
88
  const isMobile = deviceType === DeviceType.MOBILE;
90
- let disable = getSelectedDcmtsOrFocused(selectedItems, focusedItem).length === 0;
91
- let dcmtsReturned = (searchResults?.length > 1 ? selectedSearchResult?.dcmtsReturned : searchResults[0]?.dcmtsReturned ?? 0);
92
- let dcmtsFound = (searchResults?.length > 1 ? selectedSearchResult?.dcmtsFound : searchResults[0]?.dcmtsFound ?? 0);
89
+ const disable = getSelectedDcmtsOrFocused(selectedItems, focusedItem).length === 0;
90
+ // Disable the "Sign/Approve" button if:
91
+ // 1. No document or multiple documents are selected, OR
92
+ // 2. Exactly one document is selected but its FILEEXT property is null
93
+ const disableSignApproveDisable = getSelectedDcmtsOrFocused(selectedItems, focusedItem).length !== 1 || (getSelectedDcmtsOrFocused(selectedItems, focusedItem).length === 1 && getSelectedDcmtsOrFocused(selectedItems, focusedItem)[0].FILEEXT === null);
94
+ const dcmtsReturned = (searchResults?.length > 1 ? selectedSearchResult?.dcmtsReturned : searchResults[0]?.dcmtsReturned ?? 0);
95
+ const dcmtsFound = (searchResults?.length > 1 ? selectedSearchResult?.dcmtsFound : searchResults[0]?.dcmtsFound ?? 0);
93
96
  useEffect(() => { setID(genUniqueId()); }, []);
94
97
  useEffect(() => {
95
98
  setSelectedItems([]);
@@ -370,8 +373,8 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
370
373
  setIsOpenBatchUpdate(false);
371
374
  setIsModifiedBatchUpdate(false);
372
375
  await refreshSelectionDataRowsAsync();
373
- }, onStatusChanged: (isModified) => { setIsModifiedBatchUpdate(isModified); } }), showToppyForApprove && !showApprovePopup && !showRejectPopup && !showReAssignPopup && !showMoreInfoPopup &&
374
- _jsx(ToppyHelpCenter, { deviceType: deviceType, content: _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: _jsx(WorkFlowOperationButtons, { deviceType: deviceType, onApprove: () => setShowApprovePopup(true), onSignApprove: () => ShowAlert({ message: 'TODO', mode: 'info', title: SDKUI_Localizator.SignatureAndApprove, duration: 3000 }), onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), onMoreInfo: () => setShowMoreInfoPopup(true), approveDisable: disable, signApproveDisable: disable, rejectDisable: disable, reassignDisable: disable, infoDisable: getSelectedDcmtsOrFocused(selectedItems, focusedItem).length !== 1 }) }) })] }), _jsx(ConfirmFormatDialog, {}), _jsx(ConfirmAttachmentsDialog, {}), (floatingActionConfig && floatingActionConfig.isVisible) && _jsx(TMSearchResultFloatingActionButton, { selectedDcmtsOrFocused: getSelectedDcmtsOrFocused(selectedItems, focusedItem), config: floatingActionConfig })] }), [
376
+ }, onStatusChanged: (isModified) => { setIsModifiedBatchUpdate(isModified); } }), (showToppyForApprove && !showApprovePopup && !showRejectPopup && !showReAssignPopup && !showMoreInfoPopup && !openS4TViewer) &&
377
+ _jsx(ToppyHelpCenter, { deviceType: deviceType, content: _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: _jsx(WorkFlowOperationButtons, { deviceType: deviceType, onApprove: () => setShowApprovePopup(true), onSignApprove: () => onOpenS4TViewerRequest?.(getSelectedDcmtsOrFocused(selectedItems, focusedItem)), onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), onMoreInfo: () => setShowMoreInfoPopup(true), approveDisable: disable, signApproveDisable: disableSignApproveDisable, rejectDisable: disable, reassignDisable: disable, infoDisable: getSelectedDcmtsOrFocused(selectedItems, focusedItem).length !== 1 }) }) })] }), _jsx(ConfirmFormatDialog, {}), _jsx(ConfirmAttachmentsDialog, {}), (floatingActionConfig && floatingActionConfig.isVisible) && _jsx(TMSearchResultFloatingActionButton, { selectedDcmtsOrFocused: getSelectedDcmtsOrFocused(selectedItems, focusedItem), config: floatingActionConfig })] }), [
375
378
  searchResults,
376
379
  selectedSearchResult,
377
380
  lastUpdateSearchTime,
@@ -59,7 +59,7 @@ const StyledHorizontalContainer = styled.div `
59
59
  `;
60
60
  export const WorkFlowOperationButtons = ({ deviceType = DeviceType.DESKTOP, approveDisable = false, signApproveDisable = false, reassignDisable = false, rejectDisable = false, infoDisable = false, onApprove, onSignApprove, onReAssign, onReject, onMoreInfo }) => {
61
61
  const isMobile = deviceType === DeviceType.MOBILE;
62
- return (_jsxs(StyledWorkFlowOperationButtonsContainer, { "$isMobile": isMobile, children: [_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconApply, {}), caption: SDKUI_Localizator.Approve, disabled: approveDisable, onClick: () => !approveDisable && onApprove?.(), advancedColor: TMColors.success, color: 'success' }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconSignature, {}), caption: SDKUI_Localizator.SignatureAndApprove, width: '160px', disabled: approveDisable, onClick: () => !signApproveDisable && onSignApprove?.(), advancedColor: TMColors.success, color: 'success' }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconCloseOutline, {}), caption: SDKUI_Localizator.Reject, disabled: rejectDisable, onClick: () => !rejectDisable && onReject?.(), advancedColor: TMColors.error, color: 'error' }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconUser, { fontSize: 16 }), caption: SDKUI_Localizator.Reassign, disabled: reassignDisable, onClick: () => !reassignDisable && onReAssign?.(), advancedColor: TMColors.tertiary, color: 'tertiary' }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconInfo, { fontSize: 16 }), caption: SDKUI_Localizator.MoreInformation, width: '180px', disabled: infoDisable, onClick: () => !infoDisable && onMoreInfo?.(), advancedColor: TMColors.info, color: 'info' })] }));
62
+ return (_jsxs(StyledWorkFlowOperationButtonsContainer, { "$isMobile": isMobile, children: [_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconApply, {}), caption: SDKUI_Localizator.Approve, disabled: approveDisable, onClick: () => !approveDisable && onApprove?.(), advancedColor: TMColors.success, color: 'success' }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconSignature, {}), caption: SDKUI_Localizator.SignatureAndApprove, width: '160px', disabled: signApproveDisable, onClick: () => !signApproveDisable && onSignApprove?.(), advancedColor: TMColors.success, color: 'success' }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconCloseOutline, {}), caption: SDKUI_Localizator.Reject, disabled: rejectDisable, onClick: () => !rejectDisable && onReject?.(), advancedColor: TMColors.error, color: 'error' }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconUser, { fontSize: 16 }), caption: SDKUI_Localizator.Reassign, disabled: reassignDisable, onClick: () => !reassignDisable && onReAssign?.(), advancedColor: TMColors.tertiary, color: 'tertiary' }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconInfo, { fontSize: 16 }), caption: SDKUI_Localizator.MoreInformation, width: '180px', disabled: infoDisable, onClick: () => !infoDisable && onMoreInfo?.(), advancedColor: TMColors.info, color: 'info' })] }));
63
63
  };
64
64
  export const WorkFlowApproveRejectPopUp = ({ TID = 0, DID = 0, deviceType = DeviceType.DESKTOP, isReject, selectedItems = [], onClose, onCompleted }) => {
65
65
  const [commentValue, setCommentValue] = useState('');
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useMemo, useState } from 'react';
3
3
  import styled from 'styled-components';
4
4
  import { useTMPanelManagerContext } from './TMPanelManagerContext';
@@ -20,36 +20,50 @@ export const StyledToolbarButton = styled.button `
20
20
  cursor: ${({ $isDisabled }) => ($isDisabled ? 'not-allowed' : 'pointer')};
21
21
  opacity: ${({ $isDisabled }) => ($isDisabled ? 0.6 : 1)};
22
22
  background: ${({ $isActive }) => $isActive ? 'rgba(255,255,255,0.35)' : 'transparent'};
23
+ position: relative;
23
24
  &:hover {
24
25
  background: ${({ $isDisabled }) => !$isDisabled ? 'rgba(255,255,255,0.35)' : undefined};
25
26
  }
26
27
  `;
28
+ const Badge = styled.span `
29
+ position: absolute;
30
+ top: 2px;
31
+ right: 2px;
32
+ background: #ff5252;
33
+ color: white;
34
+ font-size: 10px;
35
+ min-width: 14px;
36
+ height: 14px;
37
+ padding: 0 4px;
38
+ border-radius: 999px;
39
+ display: flex;
40
+ align-items: center;
41
+ justify-content: center;
42
+ line-height: 1;
43
+ `;
27
44
  const TMPanelManagerToolbar = (props) => {
28
45
  const { panels } = props;
29
- // Get panel visibility toggling function and visibility state from context
30
46
  const { togglePanelVisibility, countVisibleLeafPanels, panelVisibility, toolbarButtonsDisabled, toolbarButtonsVisibility } = useTMPanelManagerContext();
31
- // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook
32
47
  const deviceType = useDeviceType();
33
- // This avoids unnecessary re-renders by only recalculating when deviceType changes
34
48
  let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
35
49
  const [visibleLeafPanels, setVisibleLeafPanels] = useState([]);
36
50
  useEffect(() => {
37
- // Flatten panels, filter visible leaf nodes, and sort by orderNumber
38
51
  const visibleLeafPanelsSorted = flattenPanels(panels)
39
52
  .filter(panel => toolbarButtonsVisibility[panel.id] && !panel.children?.length)
40
53
  .sort((a, b) => (a.toolbarOptions?.orderNumber ?? 0) - (b.toolbarOptions?.orderNumber ?? 0));
41
- // Update state with the filtered and sorted leaf panels for the toolbar
42
54
  setVisibleLeafPanels(visibleLeafPanelsSorted);
43
- }, [toolbarButtonsVisibility]);
44
- // Callback for toolbar button click, prevents hiding the last visible panel to ensure at least one panel is always visible
55
+ }, [toolbarButtonsVisibility, panels]);
45
56
  const onClickCallback = (panelId, isActive) => {
46
- // If the panel is currently active and it's the only visible panel, do nothing
47
57
  if (isActive && countVisibleLeafPanels() <= 1) {
48
- return undefined; // Prevent hiding the last visible panel
58
+ return undefined;
49
59
  }
50
- // Otherwise, toggle the panel visibility normally
51
60
  togglePanelVisibility(panelId);
52
61
  };
62
+ const formatCount = (count) => {
63
+ if (count > 999)
64
+ return "999+";
65
+ return count.toString();
66
+ };
53
67
  return (_jsx("div", { style: {
54
68
  display: 'flex',
55
69
  flexDirection: isMobile ? 'row' : 'column',
@@ -61,7 +75,8 @@ const TMPanelManagerToolbar = (props) => {
61
75
  }, children: visibleLeafPanels.filter(panel => toolbarButtonsVisibility[panel.id]).map(visibleLeafPanel => {
62
76
  const isActive = panelVisibility[visibleLeafPanel.id];
63
77
  const isDisabled = toolbarButtonsDisabled[visibleLeafPanel.id];
64
- return _jsx(TMTooltip, { content: visibleLeafPanel.name, position: isMobile ? 'top' : 'left', children: _jsx(StyledToolbarButton, { disabled: isDisabled, "$isDisabled": isDisabled, onClick: () => onClickCallback(visibleLeafPanel.id, isActive), "$isActive": isActive || visibleLeafPanel.toolbarOptions?.alwaysActiveColor, children: typeof visibleLeafPanel.toolbarOptions?.icon === 'string' ? (_jsx("i", { className: `dx-icon dx-icon-${visibleLeafPanel.toolbarOptions?.icon}` })) : (visibleLeafPanel.toolbarOptions?.icon) }, visibleLeafPanel.id) }, visibleLeafPanel.id);
78
+ const count = visibleLeafPanel.toolbarOptions?.count ?? 0;
79
+ return _jsx(TMTooltip, { content: visibleLeafPanel.name + (count > 0 ? ": " + count : ''), position: isMobile ? 'top' : 'left', children: _jsxs(StyledToolbarButton, { disabled: isDisabled, "$isDisabled": isDisabled, onClick: () => onClickCallback(visibleLeafPanel.id, isActive), "$isActive": isActive || visibleLeafPanel.toolbarOptions?.alwaysActiveColor, children: [typeof visibleLeafPanel.toolbarOptions?.icon === 'string' ? (_jsx("i", { className: `dx-icon dx-icon-${visibleLeafPanel.toolbarOptions?.icon}` })) : (visibleLeafPanel.toolbarOptions?.icon), (!isActive && count > 0) && _jsxs(Badge, { children: [" ", formatCount(count), " "] })] }, visibleLeafPanel.id) }, visibleLeafPanel.id);
65
80
  }) }));
66
81
  };
67
82
  export default TMPanelManagerToolbar;
@@ -21,6 +21,7 @@ export interface TMPanelDefinition {
21
21
  orderNumber?: number;
22
22
  beginGroup?: boolean;
23
23
  alwaysActiveColor?: boolean;
24
+ count?: number;
24
25
  };
25
26
  }
26
27
  export interface TMPanelHierarchyInfo {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.15.73",
3
+ "version": "6.15.75",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",