@topconsultnpm/sdkui-react 6.20.0 → 6.21.0-dev1.2

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.
Files changed (29) hide show
  1. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +7 -1
  2. package/lib/components/base/TMWaitPanel.js +6 -5
  3. package/lib/components/features/archive/TMArchive.d.ts +1 -1
  4. package/lib/components/features/archive/TMArchive.js +2 -2
  5. package/lib/components/features/documents/TMDcmtBlog.d.ts +1 -0
  6. package/lib/components/features/documents/TMDcmtBlog.js +2 -1
  7. package/lib/components/features/documents/TMDcmtForm.d.ts +42 -34
  8. package/lib/components/features/documents/TMDcmtForm.js +280 -639
  9. package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +34 -0
  10. package/lib/components/features/documents/TMDcmtFormActionButtons.js +124 -0
  11. package/lib/components/features/search/TMSearch.d.ts +2 -2
  12. package/lib/components/features/search/TMSearch.js +3 -3
  13. package/lib/components/features/search/TMSearchResult.d.ts +27 -26
  14. package/lib/components/features/search/TMSearchResult.js +349 -486
  15. package/lib/components/features/tasks/TMTaskForm.d.ts +2 -1
  16. package/lib/components/features/tasks/TMTaskForm.js +2 -2
  17. package/lib/helper/checkinCheckoutManager.js +6 -2
  18. package/lib/hooks/useCheckInOutOperations.d.ts +7 -6
  19. package/lib/hooks/useCheckInOutOperations.js +9 -16
  20. package/lib/hooks/useDcmtOperations.d.ts +3 -2
  21. package/lib/hooks/useDcmtOperations.js +2 -2
  22. package/lib/hooks/useDocumentOperations.d.ts +139 -0
  23. package/lib/hooks/useDocumentOperations.js +1275 -0
  24. package/lib/hooks/useRelatedDocuments.d.ts +1 -1
  25. package/lib/ts/types.d.ts +2 -1
  26. package/lib/ts/types.js +1 -0
  27. package/package.json +55 -55
  28. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +0 -11
  29. package/lib/components/features/search/TMSearchResultsMenuItems.js +0 -758
@@ -146,6 +146,7 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
146
146
  const isLocalChange = useRef(false);
147
147
  const dragStartPosition = useRef(null);
148
148
  const isItemsInitialized = useRef(false);
149
+ const hasReceivedNonEmptyExternalIds = useRef(false);
149
150
  useEffect(() => {
150
151
  floatingBarItemIds.current = new Set(state.items.map(i => i.id));
151
152
  floatingBarItemNames.current = new Set(state.items.map(i => i.name));
@@ -264,9 +265,14 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
264
265
  }
265
266
  if (externalPinnedItemIds === undefined || !enableConfigMode)
266
267
  return;
268
+ // Track if we've ever received non-empty external IDs
269
+ if (externalPinnedItemIds.length > 0) {
270
+ hasReceivedNonEmptyExternalIds.current = true;
271
+ }
267
272
  // Skip sync if external is empty but we have initialized items (first login case)
268
273
  // The parent hook starts with [] but we've initialized with defaults
269
- if (externalPinnedItemIds.length === 0 && state.items.length > 0)
274
+ // However, once we've received non-empty pinnedItemIds, an empty array means user removed all items
275
+ if (externalPinnedItemIds.length === 0 && state.items.length > 0 && !hasReceivedNonEmptyExternalIds.current)
270
276
  return;
271
277
  const flatItems = flattenMenuItems(contextMenuItems);
272
278
  // Build items from external pinned IDs
@@ -33,17 +33,18 @@ const StyledProgressText = styled.p ` font-weight: bold; color: #333; margin: 0;
33
33
  const StyledMessage = styled.p ` color: #666; font-size: 0.9em; margin-top: 10px; `;
34
34
  const StyledAbortButton = styled.button ` background: #ff4d4d; color: white; border: none; border-radius: 5px; padding: 10px 20px; font-size: 1em; cursor: pointer; margin-top: 20px; &:hover { background: #ff6666; } `;
35
35
  export const TMWaitPanel = (props) => {
36
+ const { title, showPrimary, textPrimary, valuePrimary, maxValuePrimary, showSecondary, textSecondary, valueSecondary, maxValueSecondary, isCancelable, abortController, onAbortClick } = props;
36
37
  const calculateProgress = (value = 0, maxValue = 0) => {
37
38
  if (maxValue === 0)
38
39
  return 0;
39
40
  const progress = (value / maxValue) * 100;
40
41
  return Number.isFinite(progress) ? progress : 0;
41
42
  };
42
- let progressValue1 = calculateProgress(props.valuePrimary, props.maxValuePrimary);
43
- let progressValue2 = calculateProgress(props.valueSecondary, props.maxValueSecondary);
44
- return (_jsx(StyledWaitPanelOverlay, { children: _jsxs(StyledWaitPanel, { "$height": (props.showPrimary && props.showSecondary) ? '350px' : '250px', children: [_jsx(StyledTitle, { children: props.title }), props.showPrimary &&
45
- _jsxs("div", { style: { width: '100%', height: '100px' }, children: [_jsx(StyledProgressBarContainer, { children: _jsx(StyledProgressBar, { style: { width: `${progressValue1.toFixed(2)}%` } }) }), _jsxs(StyledProgressText, { children: [progressValue1.toFixed(2), "%"] }), _jsx(StyledMessage, { children: props.textPrimary })] }), props.showSecondary &&
46
- _jsxs("div", { style: { width: '100%', height: '100px' }, children: [_jsx(StyledProgressBarContainer, { children: _jsx(StyledProgressBar, { style: { width: `${progressValue2.toFixed(2)}%` } }) }), _jsxs(StyledProgressText, { children: [progressValue2.toFixed(2), "%"] }), _jsx(StyledMessage, { children: props.textSecondary })] }), props.isCancelable && _jsx(StyledAbortButton, { onClick: () => props.onAbortClick?.(props.abortController), children: SDKUI_Localizator.Abort })] }) }));
43
+ let progressValue1 = calculateProgress(valuePrimary, maxValuePrimary);
44
+ let progressValue2 = calculateProgress(valueSecondary, maxValueSecondary);
45
+ return (_jsx(StyledWaitPanelOverlay, { children: _jsxs(StyledWaitPanel, { "$height": (showPrimary && showSecondary) ? '350px' : '250px', children: [_jsx(StyledTitle, { children: title }), showPrimary &&
46
+ _jsxs("div", { style: { width: '100%', height: '100px' }, children: [_jsx(StyledProgressBarContainer, { children: _jsx(StyledProgressBar, { style: { width: `${progressValue1.toFixed(2)}%` } }) }), _jsxs(StyledProgressText, { children: [progressValue1.toFixed(2), "%"] }), _jsx(StyledMessage, { children: textPrimary })] }), showSecondary &&
47
+ _jsxs("div", { style: { width: '100%', height: '100px' }, children: [_jsx(StyledProgressBarContainer, { children: _jsx(StyledProgressBar, { style: { width: `${progressValue2.toFixed(2)}%` } }) }), _jsxs(StyledProgressText, { children: [progressValue2.toFixed(2), "%"] }), _jsx(StyledMessage, { children: textSecondary })] }), isCancelable && _jsx(StyledAbortButton, { onClick: () => onAbortClick?.(abortController), children: SDKUI_Localizator.Abort })] }) }));
47
48
  };
48
49
  export const TMLayoutWaitingContainer = ({ showWaitPanel, showWaitPanelPrimary, showWaitPanelSecondary, waitPanelTitle, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, isCancelable, abortController, gap = 3, onClick, justifyContent = 'flex-start', alignItems = 'flex-start', children, direction = 'vertical' }) => {
49
50
  return (_jsxs(TMLayoutContainer, { gap: gap, justifyContent: justifyContent, alignItems: alignItems, direction: direction, children: [children, showWaitPanel && (_jsx(TMWaitPanel, { title: waitPanelTitle, showPrimary: showWaitPanelPrimary, textPrimary: waitPanelTextPrimary, valuePrimary: waitPanelValuePrimary, maxValuePrimary: waitPanelMaxValuePrimary, showSecondary: showWaitPanelSecondary, textSecondary: waitPanelTextSecondary, valueSecondary: waitPanelValueSecondary, maxValueSecondary: waitPanelMaxValueSecondary, isCancelable: isCancelable, abortController: abortController, onAbortClick: (abortController) => { setTimeout(() => { abortController?.abort(); }, 1000); } }))] }));
@@ -24,7 +24,7 @@ interface ITMArchiveProps {
24
24
  editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
25
25
  handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
26
26
  handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
27
- openPdfEditor?: (fromDTD?: DcmtTypeDescriptor, file?: File | null, handleFile?: (file: File) => void) => void;
27
+ openFileUploaderPdfEditor?: (fromDTD?: DcmtTypeDescriptor, file?: File | null, handleFile?: (file: File) => void) => void;
28
28
  onScanRequest?: (onFileScanned: (file: File) => void) => void;
29
29
  }
30
30
  declare const TMArchive: React.FunctionComponent<ITMArchiveProps>;
@@ -12,7 +12,7 @@ import TMTreeSelector from '../search/TMTreeSelector';
12
12
  import TMPanel from '../../base/TMPanel';
13
13
  import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/panelManager/TMPanelManagerContext';
14
14
  import TMPanelManagerContainer from '../../layout/panelManager/TMPanelManagerContainer';
15
- const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, connectorFileSave = undefined, onSavedAsyncCallback, inputMids = [], enableDragDropOverlay = false, passToSearch, isSharedArchive = false, inputDID = undefined, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, openPdfEditor, onScanRequest }) => {
15
+ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, connectorFileSave = undefined, onSavedAsyncCallback, inputMids = [], enableDragDropOverlay = false, passToSearch, isSharedArchive = false, inputDID = undefined, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, openFileUploaderPdfEditor, onScanRequest }) => {
16
16
  const [currentTID, setCurrentTID] = useState(inputTID ?? 0);
17
17
  const [mruTIDs, setMruTIDs] = useState([]);
18
18
  const [currentMruTID, setCurrentMruTID] = useState(0);
@@ -77,7 +77,7 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
77
77
  if (onDcmtTypeSelect)
78
78
  onDcmtTypeSelect(tidToUse);
79
79
  passToSearch(tidToUse, outputMids);
80
- } : undefined, isSharedDcmt: isSharedArchive, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, currentTID, currentTID === inputTID ? inputDID : undefined), openPdfEditor: openPdfEditor, onScanRequest: onScanRequest }, currentTID)
80
+ } : undefined, isSharedDcmt: isSharedArchive, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, currentTID, currentTID === inputTID ? inputDID : undefined), openFileUploaderPdfEditor: openFileUploaderPdfEditor, onScanRequest: onScanRequest }, currentTID)
81
81
  :
82
82
  _jsx(TMPanel, { title: 'Archiviazione', allowMaximize: false, children: _jsxs(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: [_jsx(StyledToppyTextContainer, { children: _jsx(StyledToppyText, { children: SDKUI_Localizator.DcmtTypeSelect }) }), _jsx(StyledToppyImage, { src: Logo, alt: 'Toppy' })] }) }), [currentTID, deviceType, mruTIDs, inputFile, currentInputMids, enableDragDropOverlay, isSharedArchive, allTasks]);
83
83
  const allInitialPanelVisibility = {
@@ -5,6 +5,7 @@ interface ITMDcmtBlogProps {
5
5
  did: number | undefined;
6
6
  isVisible?: boolean;
7
7
  fetchBlogDataTrigger?: number;
8
+ onRefreshBlogDatagrid?: () => Promise<void>;
8
9
  allTasks?: Array<TaskDescriptor>;
9
10
  getAllTasks?: () => Promise<void>;
10
11
  deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
@@ -8,7 +8,7 @@ import TMBlogCommentForm from '../blog/TMBlogCommentForm';
8
8
  import TMBlogsPost from '../../grids/TMBlogsPost';
9
9
  import TMSpinner from '../../base/TMSpinner';
10
10
  import { TMExceptionBoxManager } from '../../base/TMPopUp';
11
- const TMDcmtBlog = ({ tid, did, isVisible, fetchBlogDataTrigger, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
11
+ const TMDcmtBlog = ({ tid, did, isVisible, fetchBlogDataTrigger, onRefreshBlogDatagrid, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
12
12
  const [blogsDatasource, setBlogsDatasource] = useState([]);
13
13
  const [hasLoadedDataOnce, setHasLoadedDataOnce] = useState(false); //traccia se *qualsiasi* dato è stato caricato per la prima volta
14
14
  const [lastLoadedDid, setLastLoadedDid] = useState(undefined); // `lastLoadedDid` tiene traccia dell'ultimo `did` per cui abbiamo caricato i dati
@@ -58,6 +58,7 @@ const TMDcmtBlog = ({ tid, did, isVisible, fetchBlogDataTrigger, allTasks = [],
58
58
  }, [tid, did, isVisible, hasLoadedDataOnce, lastLoadedDid]);
59
59
  const refreshCallback = async () => {
60
60
  await fetchBlogDataAsync(tid, did);
61
+ await onRefreshBlogDatagrid?.();
61
62
  };
62
63
  const resetExternalBlogPost = useCallback(() => {
63
64
  setExternalBlogPost(undefined);
@@ -14,65 +14,73 @@ export declare enum InvocationContext {
14
14
  WorkflowCtrl = "workflowCtrl"
15
15
  }
16
16
  interface ITMDcmtFormProps {
17
- allTasks?: Array<TaskDescriptor>;
18
- getAllTasks?: () => Promise<void>;
19
- deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
20
- addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
21
- editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
22
- handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
23
- handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
24
17
  TID?: number;
25
18
  DID?: number;
19
+ groupId?: string;
26
20
  layoutMode?: LayoutModes;
27
21
  formMode?: FormModes;
28
- allowNavigation?: boolean;
29
- allowRelations?: boolean;
22
+ invocationContext?: InvocationContext;
30
23
  showHeader?: boolean;
24
+ showBackButton?: boolean;
31
25
  showDcmtFormSidebar?: boolean;
32
26
  isExpertMode?: boolean;
33
- count?: number;
34
- itemIndex?: number;
35
- canNext?: boolean;
36
- canPrev?: boolean;
37
27
  isClosable?: boolean;
38
- groupId?: string;
39
- invocationContext?: InvocationContext;
40
- taskFormDialogComponent?: React.ReactNode;
41
- moreInfoTasks?: Array<TaskDescriptor>;
42
- showBackButton?: boolean;
43
- onNext?: () => void;
44
- onPrev?: () => void;
45
- onClose?: () => void;
46
- onSavedAsyncCallback?: (tid: number | undefined, did: number | undefined, metadataResult?: SearchResultDescriptor | null) => Promise<void>;
47
- onSaveRecents?: (TIDs: number[]) => void;
48
- onWFOperationCompleted?: () => Promise<void>;
49
- onTaskCompleted?: (task: TaskDescriptor) => void;
50
- onTaskCreateRequest?: (taskContext: TaskContext, onTaskCreated?: (task?: TaskDescriptor) => void) => void;
51
- connectorFileSave?: () => Promise<File>;
52
28
  isModal?: boolean;
53
29
  titleModal?: string;
54
30
  widthModal?: string;
55
31
  heightModal?: string;
32
+ allowNavigation?: boolean;
33
+ count?: number;
34
+ itemIndex?: number;
35
+ canNext?: boolean;
36
+ canPrev?: boolean;
56
37
  inputFile?: File | null;
57
38
  inputMids?: Array<{
58
39
  mid: number;
59
40
  value: string;
60
41
  }>;
42
+ connectorFileSave?: () => Promise<File>;
43
+ isSharedDcmt?: boolean;
44
+ sharedSourceTID?: number;
45
+ sharedSourceDID?: number;
46
+ allowRelations?: boolean;
47
+ allowButtonsRefs?: boolean;
61
48
  openS4TViewer?: boolean;
62
- onOpenS4TViewerRequest?: (dcmtInfo: Array<DcmtInfo>, onRefreshSearchAsync?: (() => Promise<void>)) => void;
63
49
  s4TViewerDialogComponent?: React.ReactNode;
64
50
  enableDragDropOverlay?: boolean;
51
+ taskFormDialogComponent?: React.ReactNode;
52
+ allTasks?: Array<TaskDescriptor>;
53
+ moreInfoTasks?: Array<TaskDescriptor>;
54
+ onClose?: () => void;
55
+ onNext?: () => void;
56
+ onPrev?: () => void;
57
+ onSavedAsyncCallback?: (tid: number | undefined, did: number | undefined, metadataResult?: SearchResultDescriptor | null) => Promise<void>;
58
+ onSaveRecents?: (TIDs: number[]) => void;
59
+ onWFOperationCompleted?: () => Promise<void>;
60
+ getAllTasks?: () => Promise<void>;
61
+ deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
62
+ addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
63
+ editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
64
+ onTaskCompleted?: (task: TaskDescriptor) => void;
65
+ onTaskCreateRequest?: (taskContext: TaskContext, onTaskCreated?: (task?: TaskDescriptor) => void) => void;
66
+ handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
67
+ handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
68
+ onReferenceClick?: (ref: ObjectRef) => void;
65
69
  onScanRequest?: (onFileScanned: (file: File) => void) => void;
70
+ onOpenS4TViewerRequest?: (dcmtInfo: Array<DcmtInfo>, refreshDocumentPreview?: (() => Promise<void>)) => void;
71
+ onOpenPdfEditorRequest?: (dcmtInfo: Array<DcmtInfo>, refreshDocumentPreview?: (() => Promise<void>)) => void;
72
+ openFileUploaderPdfEditor?: (fromDTD?: DcmtTypeDescriptor, file?: File | null, handleFile?: (file: File) => void, refreshDocumentPreview?: () => Promise<void>) => void;
66
73
  passToSearch?: (outputMids: Array<{
67
74
  mid: number;
68
75
  value: string;
69
76
  }>, tid?: number) => void;
70
- isSharedDcmt?: boolean;
71
- sharedSourceTID?: number;
72
- sharedSourceDID?: number;
73
- allowButtonsRefs?: boolean;
74
- onReferenceClick?: (ref: ObjectRef) => void;
75
- openPdfEditor?: (fromDTD?: DcmtTypeDescriptor, file?: File | null, handleFile?: (file: File) => void) => void;
77
+ datagridUtility?: {
78
+ onRefreshSearchAsyncDatagrid?: () => Promise<void>;
79
+ onRefreshDataRowsAsync?: (() => Promise<void>);
80
+ refreshFocusedDataRowAsync?: (tid: number | undefined, did: number | undefined, refreshUI?: boolean, metadataResult?: SearchResultDescriptor | null) => Promise<void>;
81
+ onRefreshBlogDatagrid?: () => Promise<void>;
82
+ onRefreshPreviewDatagrid?: () => Promise<void>;
83
+ };
76
84
  }
77
85
  declare const TMDcmtForm: React.FC<ITMDcmtFormProps>;
78
86
  export default TMDcmtForm;