@topconsultnpm/sdkui-react 6.19.0-dev2.9 → 6.19.0-test2

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 (97) hide show
  1. package/lib/components/base/TMAccordionNew.d.ts +28 -0
  2. package/lib/components/base/TMAccordionNew.js +326 -0
  3. package/lib/components/base/TMButton.d.ts +1 -0
  4. package/lib/components/base/TMButton.js +6 -6
  5. package/lib/components/base/TMCustomButton.d.ts +1 -1
  6. package/lib/components/base/TMCustomButton.js +83 -28
  7. package/lib/components/base/TMDataGridExportForm.js +9 -3
  8. package/lib/components/base/TMFileManager.js +11 -2
  9. package/lib/components/base/TMFileManagerDataGridView.d.ts +2 -0
  10. package/lib/components/base/TMFileManagerDataGridView.js +12 -3
  11. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +2 -0
  12. package/lib/components/base/TMFileManagerThumbnailItems.js +12 -2
  13. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +2 -0
  14. package/lib/components/base/TMFileManagerThumbnailsView.js +2 -2
  15. package/lib/components/base/TMModal.d.ts +2 -0
  16. package/lib/components/base/TMModal.js +48 -3
  17. package/lib/components/base/TMPopUp.js +74 -5
  18. package/lib/components/base/TMWaitPanel.js +8 -2
  19. package/lib/components/choosers/TMDataListItemChooser.js +1 -1
  20. package/lib/components/choosers/TMDcmtTypeChooser.js +2 -2
  21. package/lib/components/choosers/TMMetadataChooser.d.ts +4 -1
  22. package/lib/components/choosers/TMMetadataChooser.js +31 -8
  23. package/lib/components/choosers/TMUserChooser.d.ts +4 -0
  24. package/lib/components/choosers/TMUserChooser.js +21 -5
  25. package/lib/components/editors/TMMetadataValues.js +45 -4
  26. package/lib/components/editors/TMTextArea.d.ts +1 -0
  27. package/lib/components/editors/TMTextArea.js +44 -10
  28. package/lib/components/editors/TMTextBox.js +34 -4
  29. package/lib/components/editors/TMTextExpression.js +36 -28
  30. package/lib/components/features/assistant/ToppyDraggableHelpCenter.d.ts +30 -0
  31. package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +471 -0
  32. package/lib/components/features/assistant/ToppySpeechBubble.d.ts +9 -0
  33. package/lib/components/features/assistant/ToppySpeechBubble.js +117 -0
  34. package/lib/components/features/blog/TMBlogCommentForm.d.ts +2 -0
  35. package/lib/components/features/blog/TMBlogCommentForm.js +18 -6
  36. package/lib/components/features/documents/TMDcmtBlog.js +1 -1
  37. package/lib/components/features/documents/TMDcmtForm.js +290 -31
  38. package/lib/components/features/documents/TMDcmtIcon.js +9 -4
  39. package/lib/components/features/documents/TMDcmtPreview.js +45 -8
  40. package/lib/components/features/documents/TMRelationViewer.js +55 -22
  41. package/lib/components/features/search/TMSearch.js +2 -2
  42. package/lib/components/features/search/TMSearchQueryEditor.js +1 -1
  43. package/lib/components/features/search/TMSearchQueryPanel.js +10 -28
  44. package/lib/components/features/search/TMSearchResult.js +102 -33
  45. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +2 -1
  46. package/lib/components/features/search/TMSearchResultsMenuItems.js +67 -28
  47. package/lib/components/features/search/TMSignSettingsForm.d.ts +9 -0
  48. package/lib/components/features/search/TMSignSettingsForm.js +621 -0
  49. package/lib/components/features/tasks/TMTaskForm.js +10 -4
  50. package/lib/components/features/tasks/TMTasksAgenda.js +1 -1
  51. package/lib/components/features/tasks/TMTasksCalendar.js +1 -1
  52. package/lib/components/features/tasks/TMTasksUtils.d.ts +1 -0
  53. package/lib/components/features/tasks/TMTasksUtils.js +17 -2
  54. package/lib/components/features/tasks/TMTasksUtilsView.js +26 -4
  55. package/lib/components/features/tasks/TMTasksView.js +11 -5
  56. package/lib/components/features/workflow/TMWorkflowPopup.js +3 -3
  57. package/lib/components/features/workflow/diagram/WFDiagram.js +19 -1
  58. package/lib/components/forms/TMSaveForm.js +3 -11
  59. package/lib/components/grids/TMBlogAttachments.d.ts +0 -14
  60. package/lib/components/grids/TMBlogAttachments.js +10 -5
  61. package/lib/components/grids/TMBlogsPost.d.ts +8 -3
  62. package/lib/components/grids/TMBlogsPost.js +100 -39
  63. package/lib/components/grids/TMBlogsPostUtils.d.ts +1 -0
  64. package/lib/components/grids/TMBlogsPostUtils.js +27 -6
  65. package/lib/components/index.d.ts +2 -1
  66. package/lib/components/index.js +2 -1
  67. package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +1 -0
  68. package/lib/components/layout/panelManager/TMPanelManagerContainer.js +2 -2
  69. package/lib/components/layout/panelManager/TMPanelManagerContext.js +0 -1
  70. package/lib/components/layout/panelManager/TMPanelManagerToolbar.js +2 -1
  71. package/lib/components/layout/panelManager/types.d.ts +1 -0
  72. package/lib/components/settings/SettingsAppearance.js +5 -5
  73. package/lib/helper/GlobalStyles.d.ts +2 -0
  74. package/lib/helper/GlobalStyles.js +10 -0
  75. package/lib/helper/Globalization.d.ts +1 -0
  76. package/lib/helper/Globalization.js +30 -0
  77. package/lib/helper/SDKUI_Localizator.d.ts +41 -1
  78. package/lib/helper/SDKUI_Localizator.js +410 -10
  79. package/lib/helper/TMIcons.d.ts +4 -1
  80. package/lib/helper/TMIcons.js +13 -1
  81. package/lib/helper/TMToppyMessage.d.ts +1 -0
  82. package/lib/helper/TMToppyMessage.js +4 -3
  83. package/lib/helper/TMUtils.d.ts +42 -4
  84. package/lib/helper/TMUtils.js +190 -23
  85. package/lib/helper/dcmtsHelper.d.ts +2 -1
  86. package/lib/helper/dcmtsHelper.js +56 -17
  87. package/lib/helper/helpers.d.ts +1 -1
  88. package/lib/helper/helpers.js +12 -17
  89. package/lib/helper/index.d.ts +1 -0
  90. package/lib/helper/index.js +1 -0
  91. package/lib/hooks/useDcmtOperations.d.ts +1 -1
  92. package/lib/hooks/useDcmtOperations.js +10 -6
  93. package/lib/hooks/useRelatedDocuments.js +35 -26
  94. package/lib/ts/types.d.ts +2 -0
  95. package/package.json +8 -8
  96. package/lib/components/features/assistant/ToppyHelpCenter.d.ts +0 -12
  97. package/lib/components/features/assistant/ToppyHelpCenter.js +0 -173
@@ -195,9 +195,18 @@ export const useRelatedDocuments = ({ selectedSearchResult, focusedItem, current
195
195
  }
196
196
  }, [selectedSearchResult?.fromTID]);
197
197
  const getFocusedItem = useCallback(() => {
198
- if (!focusedItem || currentSearchResults.length !== 1)
198
+ if (!focusedItem)
199
199
  return undefined;
200
- return { mdList: currentSearchResults[0].dtdResult?.rows?.[focusedItem?.rowIndex ?? 0], mids: currentSearchResults[0].selectMIDs ?? [] };
200
+ if (currentSearchResults.length === 1) {
201
+ return { mdList: currentSearchResults[0].dtdResult?.rows?.[focusedItem?.rowIndex ?? 0], mids: currentSearchResults[0].selectMIDs ?? [] };
202
+ }
203
+ const matchingSearchResult = currentSearchResults.find(res => res.fromTID == focusedItem?.TID);
204
+ if (!matchingSearchResult)
205
+ return undefined;
206
+ return {
207
+ mdList: matchingSearchResult.dtdResult?.rows?.[focusedItem?.rowIndex ?? 0],
208
+ mids: matchingSearchResult.selectMIDs ?? []
209
+ };
201
210
  }, [focusedItem, currentSearchResults]);
202
211
  const fetchAssociatedValues = useCallback((mid) => {
203
212
  let mdList = getFocusedItem();
@@ -222,8 +231,8 @@ export const useRelatedDocuments = ({ selectedSearchResult, focusedItem, current
222
231
  const showNoRelationsAlert = (type) => {
223
232
  ShowAlert({
224
233
  message: type === 'detail'
225
- ? "Nessun documento di dettaglio trovato per l'archiviazione."
226
- : "Nessun documento di master trovato per l'archiviazione.",
234
+ ? SDKUI_Localizator.NoDetailDocumentFoundForArchiving
235
+ : SDKUI_Localizator.NoMasterDocumentFoundForArchiving,
227
236
  mode: 'info',
228
237
  title: type === 'detail' ? SDKUI_Localizator.DcmtsDetail : SDKUI_Localizator.DcmtsMaster,
229
238
  duration: 5000
@@ -232,8 +241,8 @@ export const useRelatedDocuments = ({ selectedSearchResult, focusedItem, current
232
241
  const showNoAssociationsAlert = (type) => {
233
242
  ShowAlert({
234
243
  message: type === 'detail'
235
- ? "Nessuna associazione trovata per i documenti di dettaglio."
236
- : "Nessuna associazione trovata per i documenti di master.",
244
+ ? SDKUI_Localizator.NoMatchFoundForDetailDocuments
245
+ : SDKUI_Localizator.NoMatchFoundForMasterDocuments,
237
246
  mode: 'info',
238
247
  title: type === 'detail' ? SDKUI_Localizator.DcmtsDetail : SDKUI_Localizator.DcmtsMaster,
239
248
  duration: 5000
@@ -254,8 +263,8 @@ export const useRelatedDocuments = ({ selectedSearchResult, focusedItem, current
254
263
  if (dtd?.perm?.canArchive !== AccessLevelsEx.Yes && dtd?.perm?.canArchive !== AccessLevelsEx.Mixed) {
255
264
  ShowAlert({
256
265
  message: type === 'detail'
257
- ? "Non hai i permessi per archiviare documenti di dettaglio di questo tipo."
258
- : "Non hai i permessi per archiviare documenti master di questo tipo.",
266
+ ? SDKUI_Localizator.YouDoNotHavePermissionsToArchiveDetailDocumentsOfThisType
267
+ : SDKUI_Localizator.YouDoNotHavePermissionsToArchiveMasterDocumentsOfThisType,
259
268
  mode: 'warning',
260
269
  title: type === 'detail' ? SDKUI_Localizator.DcmtsDetail : SDKUI_Localizator.DcmtsMaster,
261
270
  duration: 5000
@@ -365,10 +374,10 @@ export const useRelatedDocuments = ({ selectedSearchResult, focusedItem, current
365
374
  if (!focusedItem?.TID || !focusedItem?.DID) {
366
375
  ShowAlert({
367
376
  message: isPairing
368
- ? "Nessun documento selezionato per l'abbinamento molti a molti."
369
- : "Nessun documento selezionato per il disabbinamento molti a molti.",
377
+ ? SDKUI_Localizator.NoDocumentSelectedForManyToManyMatching
378
+ : SDKUI_Localizator.NoDocumentSelectedForManyToManyUnmatching,
370
379
  mode: 'warning',
371
- title: isPairing ? 'Abbina documenti molti a molti' : 'Disabbina documenti molti a molti',
380
+ title: isPairing ? SDKUI_Localizator.MatchManyDocumentsManyToMany : SDKUI_Localizator.UnmatchManyDocumentsManyToMany,
372
381
  duration: 5000
373
382
  });
374
383
  return;
@@ -384,10 +393,10 @@ export const useRelatedDocuments = ({ selectedSearchResult, focusedItem, current
384
393
  if (!qd) {
385
394
  ShowAlert({
386
395
  message: isPairing
387
- ? "Nessuna query di recupero associata alla relazione di abbinamento molti a molti."
388
- : "Nessuna query di recupero associata alla relazione di disabbinamento molti a molti.",
396
+ ? SDKUI_Localizator.NoManyToManyMatchingRelationshipAssociatedWithRetrievalQuery
397
+ : SDKUI_Localizator.NoManyToManyUnmatchingRelationshipAssociatedWithRetrievalQuery,
389
398
  mode: 'warning',
390
- title: isPairing ? 'Abbina documenti molti a molti' : 'Disabbina documenti molti a molti',
399
+ title: isPairing ? SDKUI_Localizator.MatchManyDocumentsManyToMany : SDKUI_Localizator.UnmatchManyDocumentsManyToMany,
391
400
  duration: 5000
392
401
  });
393
402
  return;
@@ -490,9 +499,9 @@ export const useRelatedDocuments = ({ selectedSearchResult, focusedItem, current
490
499
  if (!isPairing) {
491
500
  if (!pairedDocumentsResult?.dtdResult?.rows || pairedDocumentsResult.dtdResult.rows.length === 0) {
492
501
  ShowAlert({
493
- message: "Nessun documento abbinato trovato.",
502
+ message: SDKUI_Localizator.NoDocumentMatchFound,
494
503
  mode: 'warning',
495
- title: 'Disabbina documenti molti a molti',
504
+ title: SDKUI_Localizator.UnmatchManyDocumentsManyToMany,
496
505
  duration: 5000
497
506
  });
498
507
  return;
@@ -514,9 +523,9 @@ export const useRelatedDocuments = ({ selectedSearchResult, focusedItem, current
514
523
  const sq = await searchEngine.SearchByIDAsync(qd);
515
524
  if (!sq?.dtdResult?.rows || sq.dtdResult.rows.length === 0) {
516
525
  ShowAlert({
517
- message: "Nessun documento trovato.",
526
+ message: SDKUI_Localizator.NoDcmtFound,
518
527
  mode: 'warning',
519
- title: 'Abbina documenti molti a molti',
528
+ title: SDKUI_Localizator.MatchManyDocumentsManyToMany,
520
529
  duration: 5000
521
530
  });
522
531
  openPairSearchModal(relation, targetTID, qd);
@@ -539,9 +548,9 @@ export const useRelatedDocuments = ({ selectedSearchResult, focusedItem, current
539
548
  };
540
549
  if (filteredRows.length === 0) {
541
550
  ShowAlert({
542
- message: "Nessun documento da abbinare. Tutti i documenti risultanti sono già abbinati.",
551
+ message: SDKUI_Localizator.NoDocumentToMatch,
543
552
  mode: 'warning',
544
- title: 'Abbina documenti molti a molti',
553
+ title: SDKUI_Localizator.MatchManyDocumentsManyToMany,
545
554
  duration: 5000
546
555
  });
547
556
  openPairSearchModal(relation, targetTID, qd);
@@ -560,10 +569,10 @@ export const useRelatedDocuments = ({ selectedSearchResult, focusedItem, current
560
569
  if (!relations.some(r => r.relationType === RelationTypes.ManyToMany)) {
561
570
  ShowAlert({
562
571
  message: isPairing
563
- ? "Nessuna relazione di abbinamento molti a molti definita nel sistema."
564
- : "Nessuna relazione di disabbinamento molti a molti definita nel sistema.",
572
+ ? SDKUI_Localizator.NoManyToManyMatchingRelationshipDefined
573
+ : SDKUI_Localizator.NoManyToManyUnmatchingRelationshipDefined,
565
574
  mode: 'warning',
566
- title: isPairing ? 'Abbina documenti molti a molti' : 'Disabbina documenti molti a molti',
575
+ title: isPairing ? SDKUI_Localizator.MatchManyDocumentsManyToMany : SDKUI_Localizator.UnmatchManyDocumentsManyToMany,
567
576
  duration: 5000
568
577
  });
569
578
  return;
@@ -572,10 +581,10 @@ export const useRelatedDocuments = ({ selectedSearchResult, focusedItem, current
572
581
  if (!manyToManyRels.some(r => r.masterTID === selectedSearchResult?.fromTID || r.detailTID === selectedSearchResult?.fromTID)) {
573
582
  ShowAlert({
574
583
  message: isPairing
575
- ? "Nessuna relazione di abbinamento molti a molti definita per il tipo di documento selezionato."
576
- : "Nessuna relazione di disabbinamento molti a molti definita per il tipo di documento selezionato.",
584
+ ? SDKUI_Localizator.NoManyToManyMatchingRelationshipDefinedForSelectedDocumentType
585
+ : SDKUI_Localizator.NoManyToManyUnmatchingRelationshipDefinedForSelectedDocumentType,
577
586
  mode: 'warning',
578
- title: isPairing ? 'Abbina documenti molti a molti' : 'Disabbina documenti molti a molti',
587
+ title: isPairing ? SDKUI_Localizator.MatchManyDocumentsManyToMany : SDKUI_Localizator.UnmatchManyDocumentsManyToMany,
579
588
  duration: 5000
580
589
  });
581
590
  return;
package/lib/ts/types.d.ts CHANGED
@@ -112,6 +112,7 @@ export type TaskContext = {
112
112
  dossier?: {
113
113
  id: number;
114
114
  name: string;
115
+ origin?: string;
115
116
  };
116
117
  document?: {
117
118
  tid: number;
@@ -172,6 +173,7 @@ export interface ITMSaveFormBaseProps {
172
173
  customTooltipSaveButton?: string;
173
174
  showBackButton?: boolean;
174
175
  showUndoButton?: boolean;
176
+ showCloseButton?: boolean;
175
177
  showWarningsCount?: boolean;
176
178
  showErrorCount?: boolean;
177
179
  hasNavigation?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react",
3
- "version": "6.19.0-dev2.9",
3
+ "version": "6.19.0-test2",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -21,12 +21,12 @@
21
21
  "@storybook/react-vite": "^10.1.0",
22
22
  "@types/htmlparser2": "^3.10.7",
23
23
  "@types/node": "^20.2.5",
24
- "@types/react": "^18.2.7",
25
- "@types/react-dom": "^18.2.4",
24
+ "@types/react": "^18.3.3",
25
+ "@types/react-dom": "^18.3.3",
26
26
  "copyfiles": "^2.4.1",
27
27
  "esbuild": "^0.25.0",
28
- "react": "^18.2.0",
29
- "react-dom": "^18.2.0",
28
+ "react": "^18.3.1",
29
+ "react-dom": "^18.3.1",
30
30
  "storybook": "^10.1.0",
31
31
  "typescript": "^5.9.3",
32
32
  "vite": "^6.1.1"
@@ -39,10 +39,10 @@
39
39
  "lib"
40
40
  ],
41
41
  "dependencies": {
42
- "@topconsultnpm/sdk-ts": "6.19.0-dev2.4",
42
+ "@topconsultnpm/sdk-ts": "6.19.0-test2",
43
43
  "buffer": "^6.0.3",
44
- "devextreme": "25.1.4",
45
- "devextreme-react": "25.1.4",
44
+ "devextreme": "25.1.7",
45
+ "devextreme-react": "25.1.7",
46
46
  "exceljs": "^4.4.0",
47
47
  "htmlparser2": "^10.0.0",
48
48
  "react-router-dom": "^6.15.0",
@@ -1,12 +0,0 @@
1
- import React from 'react';
2
- import { DeviceType } from '../../base/TMDeviceProvider';
3
- interface ToppyHelpCenterProps {
4
- content?: React.ReactNode;
5
- deviceType?: DeviceType;
6
- usePortal?: boolean;
7
- align?: 'right' | 'left';
8
- initialIsCollapsed?: boolean;
9
- onToppyImageClick?: () => void;
10
- }
11
- declare const ToppyHelpCenter: React.FC<ToppyHelpCenterProps>;
12
- export default ToppyHelpCenter;
@@ -1,173 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useState } from 'react';
3
- import ReactDOM from 'react-dom';
4
- import styled, { keyframes, css } from 'styled-components';
5
- import Toppy from '../../../assets/Toppy-generico.png';
6
- import { DeviceType } from '../../base/TMDeviceProvider';
7
- const toppyEntrance = keyframes `
8
- 0% { right: -200px; opacity: 0; }
9
- 60% { opacity: 1; }
10
- 100% { right: 10px; opacity: 1; }
11
- `;
12
- const pulseAnimation = keyframes `
13
- 0% { transform: scale(1); }
14
- 50% { transform: scale(1.05); }
15
- 100% { transform: scale(1); }
16
- `;
17
- const bounceAnimation = keyframes `
18
- 0%, 20%, 50%, 80%, 100% {
19
- transform: translateY(0);
20
- }
21
- 40% {
22
- transform: translateY(-10px);
23
- }
24
- 60% {
25
- transform: translateY(-5px);
26
- }
27
- `;
28
- const wiggle = keyframes `
29
- 0% { transform: rotate(-5deg) scale(1.1); }
30
- 10% { transform: rotate(5deg) scale(0.95); }
31
- 20% { transform: rotate(-5deg) scale(1.1); }
32
- 30% { transform: rotate(5deg) scale(1.05); }
33
- 40% { transform: rotate(-5deg) scale(1); }
34
- 50% { transform: rotate(5deg) scale(0.96); }
35
- 60% { transform: rotate(-5deg) scale(1.15); }
36
- 70% { transform: rotate(5deg) scale(0.99); }
37
- 80% { transform: rotate(-5deg) scale(1.05); }
38
- 90% { transform: rotate(5deg) scale(1); }
39
- 100% { transform: rotate(-5deg) scale(1.08); }
40
- `;
41
- const ToppyContainer = styled.div `
42
- position: ${({ $fixed }) => ($fixed ? 'fixed' : 'absolute')};
43
- bottom: ${({ $isCollapsed, $isMobile }) => $isMobile ? '5px' : $isCollapsed ? '5px' : '-20px'};
44
- ${({ $align, $isCollapsed }) => $align === 'left'
45
- ? `left: ${$isCollapsed ? '5px' : '10px'}; right: auto;`
46
- : `right: ${$isCollapsed ? '5px' : '10px'}; left: auto;`}
47
- display: flex;
48
- flex-direction: column-reverse; /* Il contenuto è sopra l'immagine */
49
- align-items: ${({ $align }) => $align === 'left' ? 'flex-start' : 'flex-end'};
50
- animation: ${({ $fixed }) => $fixed && css `${toppyEntrance} 0.5s cubic-bezier(0.23, 1, 0.32, 1)`};
51
- z-index: ${({ $fixed }) => ($fixed ? 2147483647 : 10)};
52
- `;
53
- const ToppyImage = styled.img `
54
- width: ${({ $isMobile, $isCollapsed }) => $isCollapsed ? '60px' : $isMobile ? '90px' : '120px'};
55
- height: ${({ $isMobile, $isCollapsed }) => $isCollapsed ? '70px' : $isMobile ? '105px' : '140px'};
56
- cursor: pointer;
57
- object-fit: cover;
58
- object-position: top center;
59
- clip-path: inset(0 0 22% 0 round 10px);
60
- transform: ${({ $isCollapsed, $align }) => $isCollapsed
61
- ? 'none'
62
- : $align === 'left'
63
- ? 'rotate(20deg)'
64
- : 'rotate(-20deg)'};
65
-
66
- ${({ $isCollapsed }) => $isCollapsed &&
67
- css `
68
- /* animation: ${bounceAnimation} 2s infinite; */
69
- /* animation: ${pulseAnimation} 2s infinite; */
70
- animation: ${wiggle} 4s infinite;
71
- `}
72
- `;
73
- const ToppyContent = styled.div `
74
- margin-bottom: ${({ $isMobile, $align }) => $align === 'left'
75
- ? '30px' // Spazio tra ToppyContent e ToppyImage
76
- : $isMobile
77
- ? '30px'
78
- : '20px'};
79
-
80
-
81
- display: ${props => (props.$isCollapsed ? 'none' : 'block')};
82
- width: max-content;
83
- max-width: 250px;
84
- background: linear-gradient(
85
- 180deg,
86
- rgba(0, 113, 188, 0.45) 0%,
87
- rgba(27, 20, 100, 0.65) 100%
88
- );
89
- color: white;
90
- padding: 10px;
91
- border-radius: 10px;
92
- border: 1px solid #FFFFFF;
93
- opacity: ${props => (props.$isCollapsed ? 0 : 1)};
94
- transform: ${props => (props.$isCollapsed ? 'translateY(20px)' : 'translateY(0)')};
95
- transition: opacity 0.3s ease, transform 0.3s ease;
96
- pointer-events: ${props => (props.$isCollapsed ? 'none' : 'auto')};
97
- position: relative;
98
-
99
- ${({ $align, $isMobile }) => $align === 'left' &&
100
- css `
101
- position: absolute;
102
- left: 50px;
103
- right: auto;
104
- bottom: 100%;
105
- transform: translateY(-${$isMobile ? '10px' : '20px'});
106
- `}
107
-
108
- &::after {
109
- transform: ${({ $align }) => $align === 'left' ? 'skewX(15deg)' : 'skewX(-15deg)'};
110
- content: "";
111
- position: absolute;
112
- top: 100%;
113
-
114
- ${({ $align }) => $align === 'left' ? 'left: 20px; right: auto;' : 'right: 15px; left: auto;'}
115
- border-width: 32px 32px 0 0;
116
- border-style: solid;
117
- border-color: #FFFFFF transparent;
118
- display: block;
119
- width: 0;
120
- height: 0;
121
- z-index: 1;
122
- }
123
-
124
- &::before {
125
- transform: ${({ $align }) => $align === 'left' ? 'skewX(15deg)' : 'skewX(-15deg)'};
126
- content: "";
127
- position: absolute;
128
- top: 100%;
129
-
130
- ${({ $align }) => $align === 'left' ? 'left: 20px; right: auto;' : 'right: 15px; left: auto;'}
131
- border-width: 32px 32px 0 0;
132
- border-style: solid;
133
- border-color: rgba(27, 20, 100, 0.65) transparent;
134
- display: block;
135
- width: 0;
136
- height: 0;
137
- z-index: 2;
138
- }
139
- `;
140
- const ToppyHelpCenter = ({ content, deviceType, usePortal = true, align = 'right', initialIsCollapsed, onToppyImageClick }) => {
141
- const [isCollapsed, setIsCollapsed] = useState(initialIsCollapsed ?? false);
142
- const [portalContainer, setPortalContainer] = useState(null);
143
- useEffect(() => {
144
- if (initialIsCollapsed === undefined && deviceType === DeviceType.MOBILE) {
145
- setIsCollapsed(true);
146
- }
147
- }, [deviceType, initialIsCollapsed]);
148
- useEffect(() => {
149
- if (!usePortal)
150
- return;
151
- const portalRoot = document.createElement('div');
152
- portalRoot.setAttribute('id', 'toppy-portal-root');
153
- document.body.appendChild(portalRoot);
154
- setPortalContainer(portalRoot);
155
- return () => {
156
- document.body.removeChild(portalRoot);
157
- };
158
- }, [usePortal]);
159
- const toggleCollapse = (e) => {
160
- e.stopPropagation();
161
- setIsCollapsed(!isCollapsed);
162
- onToppyImageClick?.();
163
- };
164
- const isMobile = deviceType === DeviceType.MOBILE;
165
- const toppyComponent = (_jsxs(ToppyContainer, { "$isMobile": isMobile, "$isCollapsed": isCollapsed, "$fixed": usePortal, "$align": align, children: [_jsx(ToppyImage, { "$isMobile": isMobile, "$isCollapsed": isCollapsed, "$align": align, onClick: toggleCollapse, src: Toppy, alt: "Toppy" }), _jsx(ToppyContent, { "$isCollapsed": isCollapsed, "$isMobile": isMobile, "$align": align, children: content })] }));
166
- if (usePortal) {
167
- if (!portalContainer)
168
- return null;
169
- return ReactDOM.createPortal(toppyComponent, portalContainer);
170
- }
171
- return toppyComponent;
172
- };
173
- export default ToppyHelpCenter;