synapse-react-client 4.0.37 → 4.0.40
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.
- package/dist/SWC.index.js +1 -1
- package/dist/aridhia-queries/useAridhiaQuery.d.ts +6 -2
- package/dist/aridhia-queries/useAridhiaQuery.d.ts.map +1 -1
- package/dist/aridhia-queries/useAridhiaQuery.js +3 -0
- package/dist/aridhia-queries/useAridhiaQuery.js.map +1 -1
- package/dist/components/Aridhia/AridhiaAccessStatus.d.ts +2 -1
- package/dist/components/Aridhia/AridhiaAccessStatus.d.ts.map +1 -1
- package/dist/components/Aridhia/AridhiaAccessStatus.js +60 -37
- package/dist/components/Aridhia/AridhiaAccessStatus.js.map +1 -1
- package/dist/components/Aridhia/AridhiaDarStatusPopover.d.ts +12 -0
- package/dist/components/Aridhia/AridhiaDarStatusPopover.d.ts.map +1 -0
- package/dist/components/Aridhia/AridhiaDarStatusPopover.js +56 -0
- package/dist/components/Aridhia/AridhiaDarStatusPopover.js.map +1 -0
- package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.d.ts.map +1 -1
- package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.js +38 -30
- package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.js.map +1 -1
- package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.js +15 -14
- package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.js.map +1 -1
- package/dist/components/Aridhia/RdcaDapEligibilityDialog.d.ts +11 -0
- package/dist/components/Aridhia/RdcaDapEligibilityDialog.d.ts.map +1 -0
- package/dist/components/Aridhia/RdcaDapEligibilityDialog.js +37 -0
- package/dist/components/Aridhia/RdcaDapEligibilityDialog.js.map +1 -0
- package/dist/components/Aridhia/aridhiaAccessStatusUtils.js +2 -2
- package/dist/components/Aridhia/aridhiaAccessStatusUtils.js.map +1 -1
- package/dist/components/Aridhia/aridhiaFairPortalUrls.d.ts +10 -0
- package/dist/components/Aridhia/aridhiaFairPortalUrls.d.ts.map +1 -0
- package/dist/components/Aridhia/aridhiaFairPortalUrls.js +11 -0
- package/dist/components/Aridhia/aridhiaFairPortalUrls.js.map +1 -0
- package/dist/components/Aridhia/rdcaDapConstants.d.ts +3 -0
- package/dist/components/Aridhia/rdcaDapConstants.d.ts.map +1 -0
- package/dist/components/Aridhia/rdcaDapConstants.js +6 -0
- package/dist/components/Aridhia/rdcaDapConstants.js.map +1 -0
- package/dist/components/DataExplorer/DataExplorer.css +1 -1
- package/dist/components/DataExplorer/DataExplorer.d.ts.map +1 -1
- package/dist/components/DataExplorer/DataExplorer.js +50 -50
- package/dist/components/DataExplorer/DataExplorer.js.map +1 -1
- package/dist/components/DataExplorer/DataExplorer.module.js +16 -16
- package/dist/components/DataExplorer/DataExplorer.module.js.map +1 -1
- package/dist/components/DataExplorer/DataExplorer.module.scss +29 -6
- package/dist/components/DataGrid/columns/DateTimeColumn.d.ts +16 -7
- package/dist/components/DataGrid/columns/DateTimeColumn.d.ts.map +1 -1
- package/dist/components/DataGrid/columns/DateTimeColumn.js +79 -57
- package/dist/components/DataGrid/columns/DateTimeColumn.js.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.d.ts.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.js +11 -8
- package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
- package/dist/components/DatePicker/DatePicker.d.ts +10 -0
- package/dist/components/DatePicker/DatePicker.d.ts.map +1 -0
- package/dist/components/DatePicker/DatePicker.js +18 -0
- package/dist/components/DatePicker/DatePicker.js.map +1 -0
- package/dist/components/EntityCitation/EntityCitation.d.ts.map +1 -1
- package/dist/components/EntityCitation/EntityCitation.js +8 -5
- package/dist/components/EntityCitation/EntityCitation.js.map +1 -1
- package/dist/components/HasAccess/AccessIcon.d.ts +3 -1
- package/dist/components/HasAccess/AccessIcon.d.ts.map +1 -1
- package/dist/components/HasAccess/AccessIcon.js +11 -1
- package/dist/components/HasAccess/AccessIcon.js.map +1 -1
- package/dist/components/PortalHomePageHeader/PortalHomePageHeader.d.ts +2 -1
- package/dist/components/PortalHomePageHeader/PortalHomePageHeader.d.ts.map +1 -1
- package/dist/components/PortalHomePageHeader/PortalHomePageHeader.js +81 -53
- package/dist/components/PortalHomePageHeader/PortalHomePageHeader.js.map +1 -1
- package/dist/components/ProjectInfo/ProjectInfo.d.ts.map +1 -1
- package/dist/components/ProjectInfo/ProjectInfo.js +3 -2
- package/dist/components/ProjectInfo/ProjectInfo.js.map +1 -1
- package/dist/components/QueryBuilder/FilterConditionRow.css +1 -0
- package/dist/components/QueryBuilder/FilterConditionRow.d.ts +6 -0
- package/dist/components/QueryBuilder/FilterConditionRow.d.ts.map +1 -0
- package/dist/components/QueryBuilder/FilterConditionRow.js +257 -0
- package/dist/components/QueryBuilder/FilterConditionRow.js.map +1 -0
- package/dist/components/QueryBuilder/FilterConditionRow.module.js +17 -0
- package/dist/components/QueryBuilder/FilterConditionRow.module.js.map +1 -0
- package/dist/components/QueryBuilder/FilterConditionRow.module.scss +106 -0
- package/dist/components/QueryBuilder/FilterGroupNode.css +1 -0
- package/dist/components/QueryBuilder/FilterGroupNode.d.ts +7 -0
- package/dist/components/QueryBuilder/FilterGroupNode.d.ts.map +1 -0
- package/dist/components/QueryBuilder/FilterGroupNode.js +100 -0
- package/dist/components/QueryBuilder/FilterGroupNode.js.map +1 -0
- package/dist/components/QueryBuilder/FilterGroupNode.module.js +15 -0
- package/dist/components/QueryBuilder/FilterGroupNode.module.js.map +1 -0
- package/dist/components/QueryBuilder/FilterGroupNode.module.scss +83 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.css +1 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.d.ts +21 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.d.ts.map +1 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.js +138 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.js.map +1 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.module.js +17 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.module.js.map +1 -0
- package/dist/components/QueryBuilder/QueryBuilderControls.module.scss +79 -0
- package/dist/components/QueryBuilder/QueryBuilderInternalContext.d.ts +39 -0
- package/dist/components/QueryBuilder/QueryBuilderInternalContext.d.ts.map +1 -0
- package/dist/components/QueryBuilder/QueryBuilderInternalContext.js +19 -0
- package/dist/components/QueryBuilder/QueryBuilderInternalContext.js.map +1 -0
- package/dist/components/QueryBuilder/qbTreeToReadable.d.ts +14 -0
- package/dist/components/QueryBuilder/qbTreeToReadable.d.ts.map +1 -0
- package/dist/components/QueryBuilder/qbTreeToReadable.js +89 -0
- package/dist/components/QueryBuilder/qbTreeToReadable.js.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderId.d.ts +2 -0
- package/dist/components/QueryBuilder/queryBuilderId.d.ts.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderId.js +9 -0
- package/dist/components/QueryBuilder/queryBuilderId.js.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderMetadata.d.ts +24 -0
- package/dist/components/QueryBuilder/queryBuilderMetadata.d.ts.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderMetadata.js +91 -0
- package/dist/components/QueryBuilder/queryBuilderMetadata.js.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderOperations.d.ts +58 -0
- package/dist/components/QueryBuilder/queryBuilderOperations.d.ts.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderOperations.js +200 -0
- package/dist/components/QueryBuilder/queryBuilderOperations.js.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderTranslation.d.ts +3 -2
- package/dist/components/QueryBuilder/queryBuilderTranslation.d.ts.map +1 -1
- package/dist/components/QueryBuilder/queryBuilderTranslation.js +82 -84
- package/dist/components/QueryBuilder/queryBuilderTranslation.js.map +1 -1
- package/dist/components/QueryBuilder/useQBCombinedSql.d.ts +11 -0
- package/dist/components/QueryBuilder/useQBCombinedSql.d.ts.map +1 -0
- package/dist/components/QueryBuilder/useQBCombinedSql.js +29 -0
- package/dist/components/QueryBuilder/useQBCombinedSql.js.map +1 -0
- package/dist/components/QueryBuilder/useQBFacetSourceMetadata.d.ts +18 -0
- package/dist/components/QueryBuilder/useQBFacetSourceMetadata.d.ts.map +1 -0
- package/dist/components/QueryBuilder/useQBFacetSourceMetadata.js +27 -0
- package/dist/components/QueryBuilder/useQBFacetSourceMetadata.js.map +1 -0
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts +14 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js +185 -120
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
- package/dist/components/RssFeedCards/RssFeedCards.d.ts +1 -0
- package/dist/components/RssFeedCards/RssFeedCards.d.ts.map +1 -1
- package/dist/components/RssFeedCards/RssFeedCards.js +11 -11
- package/dist/components/RssFeedCards/RssFeedCards.js.map +1 -1
- package/dist/components/SynapseChat/SynapseChat.d.ts +7 -1
- package/dist/components/SynapseChat/SynapseChat.d.ts.map +1 -1
- package/dist/components/SynapseChat/SynapseChat.js +76 -71
- package/dist/components/SynapseChat/SynapseChat.js.map +1 -1
- package/dist/components/SynapseChat/SynapsePortalChatDialog.d.ts +3 -1
- package/dist/components/SynapseChat/SynapsePortalChatDialog.d.ts.map +1 -1
- package/dist/components/SynapseChat/SynapsePortalChatDialog.js +24 -13
- package/dist/components/SynapseChat/SynapsePortalChatDialog.js.map +1 -1
- package/dist/components/SynapseChat/portalChatSessionStorage.d.ts +23 -0
- package/dist/components/SynapseChat/portalChatSessionStorage.d.ts.map +1 -0
- package/dist/components/SynapseChat/portalChatSessionStorage.js +29 -0
- package/dist/components/SynapseChat/portalChatSessionStorage.js.map +1 -0
- package/dist/components/SynapseHomepageV2/HotdropsAndNews.css +1 -1
- package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.js +9 -9
- package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.js.map +1 -1
- package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.scss +1 -0
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.d.ts +6 -0
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.d.ts.map +1 -1
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.js +92 -79
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.js.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.d.ts +3 -4
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.d.ts.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js +2 -2
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.js +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.js.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.d.ts.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.js +9 -2
- package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
- package/dist/components/entity/page/title_bar/EntityPageTitleBar.js +1 -1
- package/dist/components/entity/page/title_bar/EntityPageTitleBar.js.map +1 -1
- package/dist/components/menu/ComplexMenu.js +1 -1
- package/dist/components/menu/ComplexMenu.js.map +1 -1
- package/dist/components/menu/DropdownMenu.d.ts.map +1 -1
- package/dist/components/menu/DropdownMenu.js +4 -0
- package/dist/components/menu/DropdownMenu.js.map +1 -1
- package/dist/features/entity/metadata-task/hooks/useMarkCurationTaskInProgress.d.ts +10 -0
- package/dist/features/entity/metadata-task/hooks/useMarkCurationTaskInProgress.d.ts.map +1 -0
- package/dist/features/entity/metadata-task/hooks/useMarkCurationTaskInProgress.js +20 -0
- package/dist/features/entity/metadata-task/hooks/useMarkCurationTaskInProgress.js.map +1 -0
- package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.js +29 -20
- package/dist/features/entity/metadata-task/hooks/useOpenCuratorButton.js.map +1 -1
- package/dist/mocks/accessRequirement/mockFormTemplates.d.ts +16 -0
- package/dist/mocks/accessRequirement/mockFormTemplates.d.ts.map +1 -0
- package/dist/mocks/accessRequirement/mockFormTemplates.js +70 -0
- package/dist/mocks/accessRequirement/mockFormTemplates.js.map +1 -0
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.d.ts +7 -0
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.d.ts.map +1 -0
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.js +47 -0
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.js.map +1 -0
- package/dist/mocks/accessRequirement/mockJsonSchemas.d.ts +24 -0
- package/dist/mocks/accessRequirement/mockJsonSchemas.d.ts.map +1 -0
- package/dist/mocks/accessRequirement/mockJsonSchemas.js +62 -0
- package/dist/mocks/accessRequirement/mockJsonSchemas.js.map +1 -0
- package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts +18 -1
- package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/aridhiaHandlers.js +39 -33
- package/dist/mocks/msw/handlers/aridhiaHandlers.js.map +1 -1
- package/dist/mocks/msw/handlers/formTemplateHandlers.d.ts +5 -0
- package/dist/mocks/msw/handlers/formTemplateHandlers.d.ts.map +1 -0
- package/dist/mocks/msw/handlers/formTemplateHandlers.js +65 -0
- package/dist/mocks/msw/handlers/formTemplateHandlers.js.map +1 -0
- package/dist/mocks/msw/handlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers.js +49 -47
- package/dist/mocks/msw/handlers.js.map +1 -1
- package/dist/style/abstracts/_cssVariables.scss +7 -0
- package/dist/style/components/_query-wrapper-plot-nav.scss +9 -0
- package/dist/style/main.css +1 -1
- package/dist/synapse-queries/KeyFactory.d.ts +6 -1
- package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
- package/dist/synapse-queries/KeyFactory.js +17 -2
- package/dist/synapse-queries/KeyFactory.js.map +1 -1
- package/dist/synapse-queries/chat/useChat.d.ts.map +1 -1
- package/dist/synapse-queries/chat/useChat.js +2 -4
- package/dist/synapse-queries/chat/useChat.js.map +1 -1
- package/dist/synapse-queries/dataaccess/index.d.ts +2 -0
- package/dist/synapse-queries/dataaccess/index.d.ts.map +1 -1
- package/dist/synapse-queries/dataaccess/index.js +5 -3
- package/dist/synapse-queries/dataaccess/useFormTemplate.d.ts +41 -0
- package/dist/synapse-queries/dataaccess/useFormTemplate.d.ts.map +1 -0
- package/dist/synapse-queries/dataaccess/useFormTemplate.js +63 -0
- package/dist/synapse-queries/dataaccess/useFormTemplate.js.map +1 -0
- package/dist/synapse-queries/dataaccess/useGenerateDataAccessSchema.d.ts +21 -0
- package/dist/synapse-queries/dataaccess/useGenerateDataAccessSchema.d.ts.map +1 -0
- package/dist/synapse-queries/dataaccess/useGenerateDataAccessSchema.js +34 -0
- package/dist/synapse-queries/dataaccess/useGenerateDataAccessSchema.js.map +1 -0
- package/dist/synapse-queries/index.js +190 -180
- package/dist/testutils/ReactQueryMockUtils.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/featureflag/FeatureFlags.d.ts +0 -1
- package/dist/utils/featureflag/FeatureFlags.d.ts.map +1 -1
- package/dist/utils/featureflag/FeatureFlags.js +1 -1
- package/dist/utils/featureflag/FeatureFlags.js.map +1 -1
- package/dist/utils/jsonschema/getType.d.ts.map +1 -1
- package/dist/utils/jsonschema/getType.js +4 -1
- package/dist/utils/jsonschema/getType.js.map +1 -1
- package/package.json +7 -7
|
@@ -29,7 +29,13 @@ export type SynapseChatProps = {
|
|
|
29
29
|
* @default false
|
|
30
30
|
*/
|
|
31
31
|
allowAttachments?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Invoked when creating the agent session fails because the current (anonymous) user is not
|
|
34
|
+
* authorized to start a session with this agent. Callers should use this to prompt the user to
|
|
35
|
+
* log in. When omitted, the session creation error is shown inline instead.
|
|
36
|
+
*/
|
|
37
|
+
onSessionCreationUnauthenticated?: () => void;
|
|
32
38
|
};
|
|
33
|
-
export declare function SynapseChat({ initialMessage, agentRegistrationId, chatbotName, variant, agentAvatar, hideTitle, textboxPositionOffset, sessionContext, externalSession, setExternalSession, externalChatState, showAccessLevelMenu, onChatResponse, suggestedPrompts, allowAttachments, }: SynapseChatProps): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
export declare function SynapseChat({ initialMessage, agentRegistrationId, chatbotName, variant, agentAvatar, hideTitle, textboxPositionOffset, sessionContext, externalSession, setExternalSession, externalChatState, showAccessLevelMenu, onChatResponse, suggestedPrompts, allowAttachments, onSessionCreationUnauthenticated, }: SynapseChatProps): import("react/jsx-runtime").JSX.Element;
|
|
34
40
|
export default SynapseChat;
|
|
35
41
|
//# sourceMappingURL=SynapseChat.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapseChat.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseChat/SynapseChat.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgB,MAAM,uCAAuC,CAAA;AAe/E,OAAO,EACL,YAAY,EAEZ,uBAAuB,EACxB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AAsDlE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAE9B,cAAc,CAAC,EAAE,uBAAuB,CAAA;IAExC,eAAe,CAAC,EAAE,YAAY,CAAA;IAE9B,kBAAkB,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,GAAG,SAAS,KAAK,IAAI,CAAA;IAE1D,iBAAiB,CAAC,EAAE,SAAS,CAAA;IAE7B,uBAAuB,CAAC,EAAE,gBAAgB,CAAA;IAE1C,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/C,wFAAwF;IACxF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,mDAAmD;IACnD,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"SynapseChat.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseChat/SynapseChat.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgB,MAAM,uCAAuC,CAAA;AAe/E,OAAO,EACL,YAAY,EAEZ,uBAAuB,EACxB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AAsDlE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAE9B,cAAc,CAAC,EAAE,uBAAuB,CAAA;IAExC,eAAe,CAAC,EAAE,YAAY,CAAA;IAE9B,kBAAkB,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,GAAG,SAAS,KAAK,IAAI,CAAA;IAE1D,iBAAiB,CAAC,EAAE,SAAS,CAAA;IAE7B,uBAAuB,CAAC,EAAE,gBAAgB,CAAA;IAE1C,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/C,wFAAwF;IACxF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,mDAAmD;IACnD,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B;;;;OAIG;IACH,gCAAgC,CAAC,EAAE,MAAM,IAAI,CAAA;CAC9C,CAAA;AAED,wBAAgB,WAAW,CAAC,EAC1B,cAAc,EACd,mBAAmB,EACnB,WAA2B,EAC3B,OAAmB,EACnB,WAAW,EACX,SAAiB,EACjB,qBAA6B,EAC7B,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,mBAA0B,EAC1B,cAAc,EACd,gBAAgB,EAChB,gBAAwB,EACxB,gCAAgC,GACjC,EAAE,gBAAgB,2CAmUlB;AAED,eAAe,WAAW,CAAA"}
|
|
@@ -6,25 +6,25 @@ import "../../utils/AppUtils/index.js";
|
|
|
6
6
|
import "../../utils/index.js";
|
|
7
7
|
import { SkeletonParagraph as ee } from "../Skeleton/SkeletonParagraph.js";
|
|
8
8
|
import "../Skeleton/index.js";
|
|
9
|
-
import { UserCard as
|
|
10
|
-
import { useCreateAgentSession as
|
|
11
|
-
import { useChatState as
|
|
12
|
-
import { AccessLevelMenu as
|
|
13
|
-
import { ChatInputArea as
|
|
14
|
-
import
|
|
15
|
-
import { ForwardRef as
|
|
16
|
-
import { useEffect as
|
|
17
|
-
import { Alert as
|
|
18
|
-
import { jsx as
|
|
19
|
-
import { AgentAccessLevel as
|
|
20
|
-
import { FileHandleAssociateType as
|
|
21
|
-
import { SmartToyTwoTone as
|
|
9
|
+
import { UserCard as te } from "../UserCard/UserCard.js";
|
|
10
|
+
import { useCreateAgentSession as r, useUpdateAgentSession as i } from "../../synapse-queries/chat/useChat.js";
|
|
11
|
+
import { useChatState as a } from "./useChatState.js";
|
|
12
|
+
import { AccessLevelMenu as ne } from "./AccessLevelMenu.js";
|
|
13
|
+
import { ChatInputArea as re } from "./components/ChatInputArea/ChatInputArea.js";
|
|
14
|
+
import ie from "./SynapseChatMessage.js";
|
|
15
|
+
import { ForwardRef as o } from "../../assets/illustrations/curie_avatar_head.js";
|
|
16
|
+
import { useEffect as s, useRef as c, useState as l } from "react";
|
|
17
|
+
import { Alert as u, Box as d, Chip as f, List as p, ListItem as m, Stack as h, Typography as g } from "@mui/material";
|
|
18
|
+
import { jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
19
|
+
import { AgentAccessLevel as y } from "@sage-bionetworks/synapse-types";
|
|
20
|
+
import { FileHandleAssociateType as ae } from "@sage-bionetworks/synapse-client";
|
|
21
|
+
import { SmartToyTwoTone as b } from "@mui/icons-material";
|
|
22
22
|
//#region src/components/SynapseChat/SynapseChat.tsx
|
|
23
|
-
var
|
|
24
|
-
[
|
|
25
|
-
[
|
|
26
|
-
[
|
|
27
|
-
},
|
|
23
|
+
var oe = "Hi! How can I help you today?", se = {
|
|
24
|
+
[y.PUBLICLY_ACCESSIBLE]: " and can only read public data.",
|
|
25
|
+
[y.READ_YOUR_PRIVATE_DATA]: " and can read your public and private data in Synapse on your behalf.",
|
|
26
|
+
[y.WRITE_YOUR_PRIVATE_DATA]: " and can read and write your public and private data in Synapse on your behalf."
|
|
27
|
+
}, ce = /* @__PURE__ */ _(d, {
|
|
28
28
|
sx: {
|
|
29
29
|
p: "3px",
|
|
30
30
|
borderRadius: "50%",
|
|
@@ -34,8 +34,8 @@ var ae = "Hi! How can I help you today?", oe = {
|
|
|
34
34
|
mt: "10px",
|
|
35
35
|
height: "31px"
|
|
36
36
|
},
|
|
37
|
-
children: /* @__PURE__ */
|
|
38
|
-
}),
|
|
37
|
+
children: /* @__PURE__ */ _(b, { sx: { color: "secondary.main" } })
|
|
38
|
+
}), le = /* @__PURE__ */ _(d, {
|
|
39
39
|
sx: {
|
|
40
40
|
mt: "10px",
|
|
41
41
|
height: "30px",
|
|
@@ -44,63 +44,68 @@ var ae = "Hi! How can I help you today?", oe = {
|
|
|
44
44
|
alignItems: "center",
|
|
45
45
|
justifyContent: "center"
|
|
46
46
|
},
|
|
47
|
-
children: /* @__PURE__ */
|
|
47
|
+
children: /* @__PURE__ */ _(o, {})
|
|
48
48
|
});
|
|
49
|
-
function
|
|
50
|
-
let { accessToken: I } = t(), { userId: L } = n(), R =
|
|
49
|
+
function x({ initialMessage: o, agentRegistrationId: b, chatbotName: x = "SynapseChat", variant: S = "default", agentAvatar: C, hideTitle: w = !1, textboxPositionOffset: T = "0px", sessionContext: E, externalSession: D, setExternalSession: O, externalChatState: k, showAccessLevelMenu: A = !0, onChatResponse: j, suggestedPrompts: M, allowAttachments: N = !1, onSessionCreationUnauthenticated: P }) {
|
|
50
|
+
let { accessToken: F, isAuthenticated: I } = t(), { userId: L } = n(), R = x + " can make mistakes", z = C ?? (S === "curie" ? le : ce), B = /* @__PURE__ */ _(te, {
|
|
51
51
|
ownerId: L,
|
|
52
52
|
size: "AVATAR",
|
|
53
53
|
avatarSize: "MEDIUM"
|
|
54
|
-
}), [V,
|
|
54
|
+
}), [V, ue] = l(), H = D ?? V, U = O ?? ue, { mutate: W, error: G } = r({
|
|
55
|
+
onSuccess: (e) => U(e),
|
|
56
|
+
onError: (e) => {
|
|
57
|
+
!I && (e.status === 401 || e.status === 403) && P?.();
|
|
58
|
+
}
|
|
59
|
+
}), { mutate: de } = i({
|
|
55
60
|
onSuccess: (e) => U(e),
|
|
56
61
|
onError: (t) => e(`Unable to update the agent session: ${t.message}`, "danger")
|
|
57
|
-
}), [K,
|
|
62
|
+
}), [K, fe] = l(E ? y.WRITE_YOUR_PRIVATE_DATA : y.PUBLICLY_ACCESSIBLE), pe = a(H, j), { interactions: q, isAwaitingResponse: J, sendChat: Y } = k ?? pe, X = S === "curie" && q.length === 0, me = R + (S === "curie" ? se[K] : ""), Z = c(void 0);
|
|
58
63
|
Z.current === void 0 && (Z.current = new Set(q.map((e) => e.id)));
|
|
59
|
-
let
|
|
60
|
-
|
|
64
|
+
let he = Z.current, [ge, Q] = l(""), [$, _e] = l(!1), [ve, ye] = l([]);
|
|
65
|
+
s(() => {
|
|
61
66
|
W && !H && W({
|
|
62
67
|
agentAccessLevel: K,
|
|
63
|
-
agentRegistrationId:
|
|
64
|
-
sessionContext:
|
|
68
|
+
agentRegistrationId: b,
|
|
69
|
+
sessionContext: E
|
|
65
70
|
});
|
|
66
71
|
}, [
|
|
67
72
|
W,
|
|
68
73
|
H,
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
F,
|
|
75
|
+
E,
|
|
71
76
|
K,
|
|
72
|
-
|
|
73
|
-
]),
|
|
74
|
-
H &&
|
|
77
|
+
b
|
|
78
|
+
]), s(() => {
|
|
79
|
+
H && o && !$ && (Y(o), _e(!0));
|
|
75
80
|
}, [
|
|
76
81
|
H,
|
|
77
|
-
|
|
82
|
+
o,
|
|
78
83
|
$,
|
|
79
84
|
Y
|
|
80
85
|
]);
|
|
81
|
-
let
|
|
86
|
+
let be = (e, t) => {
|
|
82
87
|
Y(e, t.length ? t.map((e) => ({
|
|
83
88
|
fileHandleId: e.fileHandleId,
|
|
84
89
|
associateObjectId: e.fileHandleId,
|
|
85
|
-
associateObjectType:
|
|
86
|
-
})) : void 0), Q(""),
|
|
90
|
+
associateObjectType: ae.FileEntity
|
|
91
|
+
})) : void 0), Q(""), ye(t);
|
|
87
92
|
};
|
|
88
|
-
return G ? /* @__PURE__ */
|
|
93
|
+
return G && !(!I && P && (G.status === 401 || G.status === 403)) ? /* @__PURE__ */ _(u, {
|
|
89
94
|
severity: "error",
|
|
90
95
|
sx: { my: 2 },
|
|
91
96
|
children: G.reason
|
|
92
|
-
}) : /* @__PURE__ */
|
|
97
|
+
}) : /* @__PURE__ */ v(d, {
|
|
93
98
|
sx: {
|
|
94
99
|
display: "flex",
|
|
95
100
|
flexDirection: "column",
|
|
96
|
-
justifyContent:
|
|
97
|
-
gap:
|
|
101
|
+
justifyContent: S === "curie" ? "flex-start" : "space-between",
|
|
102
|
+
gap: S === "curie" ? "20px" : "0",
|
|
98
103
|
maxWidth: "1100px",
|
|
99
104
|
mx: "auto",
|
|
100
105
|
height: "100%"
|
|
101
106
|
},
|
|
102
107
|
children: [
|
|
103
|
-
!
|
|
108
|
+
!w && /* @__PURE__ */ _(g, {
|
|
104
109
|
variant: "headline1",
|
|
105
110
|
sx: {
|
|
106
111
|
p: "20px",
|
|
@@ -111,30 +116,30 @@ function C({ initialMessage: s, agentRegistrationId: x, chatbotName: C = "Synaps
|
|
|
111
116
|
backgroundColor: "white",
|
|
112
117
|
zIndex: 1
|
|
113
118
|
},
|
|
114
|
-
children:
|
|
119
|
+
children: x
|
|
115
120
|
}),
|
|
116
|
-
|
|
121
|
+
A && S !== "curie" && I && /* @__PURE__ */ _(ne, {
|
|
117
122
|
initAccessLevel: K,
|
|
118
123
|
onChange: (e) => {
|
|
119
|
-
|
|
124
|
+
fe(e), de({
|
|
120
125
|
agentAccessLevel: e,
|
|
121
126
|
sessionId: H.sessionId
|
|
122
127
|
});
|
|
123
128
|
}
|
|
124
129
|
}),
|
|
125
|
-
!H && /* @__PURE__ */
|
|
126
|
-
H && /* @__PURE__ */
|
|
130
|
+
!H && /* @__PURE__ */ _(ee, { numRows: 10 }),
|
|
131
|
+
H && /* @__PURE__ */ _(d, {
|
|
127
132
|
sx: {
|
|
128
133
|
flexGrow: 1,
|
|
129
134
|
overflowY: "auto",
|
|
130
|
-
mb:
|
|
135
|
+
mb: S === "curie" ? 0 : 2
|
|
131
136
|
},
|
|
132
|
-
children: /* @__PURE__ */
|
|
137
|
+
children: /* @__PURE__ */ v(p, {
|
|
133
138
|
sx: {
|
|
134
139
|
flex: 1,
|
|
135
140
|
overflowY: "auto",
|
|
136
141
|
pt: "20px",
|
|
137
|
-
...
|
|
142
|
+
...S === "curie" && {
|
|
138
143
|
pt: 0,
|
|
139
144
|
pb: 0,
|
|
140
145
|
gap: "20px"
|
|
@@ -146,7 +151,7 @@ function C({ initialMessage: s, agentRegistrationId: x, chatbotName: C = "Synaps
|
|
|
146
151
|
justifyContent: "flex-end"
|
|
147
152
|
}
|
|
148
153
|
},
|
|
149
|
-
children: [X && /* @__PURE__ */
|
|
154
|
+
children: [X && /* @__PURE__ */ v(m, {
|
|
150
155
|
sx: {
|
|
151
156
|
display: "grid",
|
|
152
157
|
gridTemplateColumns: "50px auto",
|
|
@@ -155,37 +160,37 @@ function C({ initialMessage: s, agentRegistrationId: x, chatbotName: C = "Synaps
|
|
|
155
160
|
alignItems: "start",
|
|
156
161
|
p: 0
|
|
157
162
|
},
|
|
158
|
-
children: [z, /* @__PURE__ */
|
|
163
|
+
children: [z, /* @__PURE__ */ _(g, {
|
|
159
164
|
sx: {
|
|
160
165
|
justifySelf: "start",
|
|
161
166
|
mt: "14px"
|
|
162
167
|
},
|
|
163
|
-
children:
|
|
168
|
+
children: oe
|
|
164
169
|
})]
|
|
165
170
|
}), q.map((e, t) => {
|
|
166
171
|
let n = t === q.length - 1;
|
|
167
|
-
return /* @__PURE__ */
|
|
172
|
+
return /* @__PURE__ */ _(ie, {
|
|
168
173
|
agentAvatar: z,
|
|
169
174
|
userAvatar: B,
|
|
170
175
|
userMessage: e.userMessage,
|
|
171
176
|
chatJobId: e.jobId,
|
|
172
|
-
showLoadingIcon:
|
|
177
|
+
showLoadingIcon: S !== "curie",
|
|
173
178
|
onSendChat: Y,
|
|
174
179
|
scrollIntoView: n,
|
|
175
|
-
animateEntry: !
|
|
180
|
+
animateEntry: !he.has(e.id),
|
|
176
181
|
isAwaitingResponse: J,
|
|
177
|
-
pendingAttachments: n ?
|
|
182
|
+
pendingAttachments: n ? ve : void 0
|
|
178
183
|
}, e.id);
|
|
179
184
|
})]
|
|
180
185
|
})
|
|
181
186
|
}),
|
|
182
|
-
/* @__PURE__ */
|
|
187
|
+
/* @__PURE__ */ v(d, {
|
|
183
188
|
sx: {
|
|
184
189
|
position: "sticky",
|
|
185
|
-
bottom:
|
|
190
|
+
bottom: S === "curie" ? "0px" : T,
|
|
186
191
|
backgroundColor: "white"
|
|
187
192
|
},
|
|
188
|
-
children: [
|
|
193
|
+
children: [M && M.length > 0 && q.length === 0 && /* @__PURE__ */ _(h, {
|
|
189
194
|
direction: "row",
|
|
190
195
|
spacing: 1,
|
|
191
196
|
sx: {
|
|
@@ -193,37 +198,37 @@ function C({ initialMessage: s, agentRegistrationId: x, chatbotName: C = "Synaps
|
|
|
193
198
|
flexWrap: "wrap",
|
|
194
199
|
gap: 1
|
|
195
200
|
},
|
|
196
|
-
children:
|
|
201
|
+
children: M.map((e) => /* @__PURE__ */ _(f, {
|
|
197
202
|
label: e,
|
|
198
203
|
variant: "outlined",
|
|
199
204
|
onClick: () => Q(e),
|
|
200
205
|
disabled: !H,
|
|
201
206
|
sx: { cursor: "pointer" }
|
|
202
207
|
}, e))
|
|
203
|
-
}), /* @__PURE__ */
|
|
208
|
+
}), /* @__PURE__ */ _(d, {
|
|
204
209
|
sx: { mt: "5px" },
|
|
205
|
-
children: /* @__PURE__ */
|
|
206
|
-
value:
|
|
210
|
+
children: /* @__PURE__ */ _(re, {
|
|
211
|
+
value: ge,
|
|
207
212
|
onValueChange: Q,
|
|
208
|
-
onSend:
|
|
209
|
-
placeholder:
|
|
213
|
+
onSend: be,
|
|
214
|
+
placeholder: S === "curie" ? "Ask anything" : `Message ${x}`,
|
|
210
215
|
disabled: !H || J,
|
|
211
|
-
allowAttachments:
|
|
216
|
+
allowAttachments: N
|
|
212
217
|
})
|
|
213
218
|
})]
|
|
214
219
|
}),
|
|
215
|
-
/* @__PURE__ */
|
|
220
|
+
/* @__PURE__ */ _(g, {
|
|
216
221
|
variant: "smallText1",
|
|
217
222
|
sx: {
|
|
218
223
|
pt: "8px",
|
|
219
224
|
textAlign: "center"
|
|
220
225
|
},
|
|
221
|
-
children:
|
|
226
|
+
children: me
|
|
222
227
|
})
|
|
223
228
|
]
|
|
224
229
|
});
|
|
225
230
|
}
|
|
226
231
|
//#endregion
|
|
227
|
-
export {
|
|
232
|
+
export { x as SynapseChat, x as default };
|
|
228
233
|
|
|
229
234
|
//# sourceMappingURL=SynapseChat.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapseChat.js","names":[],"sources":["../../../src/components/SynapseChat/SynapseChat.tsx"],"sourcesContent":["import { ChatState, useChatState } from '@/components/SynapseChat/useChatState'\nimport {\n useCreateAgentSession,\n useUpdateAgentSession,\n} from '@/synapse-queries/chat/useChat'\nimport { useSynapseContext } from '@/utils'\nimport {\n Alert,\n Box,\n Chip,\n List,\n ListItem,\n Stack,\n Typography,\n} from '@mui/material'\nimport {\n AgentSession,\n FileHandleAssociateType,\n GridAgentSessionContext,\n} from '@sage-bionetworks/synapse-client'\nimport { AgentAccessLevel } from '@sage-bionetworks/synapse-types'\nimport { useEffect, useRef, useState } from 'react'\nimport { SkeletonParagraph } from '../Skeleton'\nimport { displayToast } from '../ToastMessage'\nimport AccessLevelMenu from './AccessLevelMenu'\nimport { ChatAttachment } from './utils/types'\nimport { ChatInputArea } from './components/ChatInputArea/ChatInputArea'\nimport SynapseChatMessage from './SynapseChatMessage'\nimport { SmartToyTwoTone } from '@mui/icons-material'\nimport { UserCard } from '../UserCard/UserCard'\nimport { useApplicationSessionContext } from '@/utils/AppUtils'\nimport { ReactComponent as CurieAvatarHead } from '@/assets/illustrations/curie_avatar_head.svg'\n\nconst CURIE_GREETING = 'Hi! How can I help you today?'\n\nconst CURIE_ACCESS_LEVEL_SUFFIX: Record<AgentAccessLevel, string> = {\n [AgentAccessLevel.PUBLICLY_ACCESSIBLE]: ' and can only read public data.',\n [AgentAccessLevel.READ_YOUR_PRIVATE_DATA]:\n ' and can read your public and private data in Synapse on your behalf.',\n [AgentAccessLevel.WRITE_YOUR_PRIVATE_DATA]:\n ' and can read and write your public and private data in Synapse on your behalf.',\n}\n\nconst DEFAULT_AVATAR = (\n <Box\n sx={{\n p: '3px',\n borderRadius: '50%',\n borderStyle: 'solid',\n borderWidth: '1px',\n borderColor: 'grey.300',\n mt: '10px',\n height: '31px',\n }}\n >\n <SmartToyTwoTone sx={{ color: 'secondary.main' }} />\n </Box>\n)\n\nconst CURIE_AVATAR = (\n <Box\n sx={{\n mt: '10px',\n height: '30px',\n width: '30px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <CurieAvatarHead />\n </Box>\n)\n\nexport type SynapseChatProps = {\n initialMessage?: string //optional initial message\n agentRegistrationId?: string // if provided, use this agent\n chatbotName?: string // optional name of this chatbot agent\n variant?: 'default' | 'curie'\n hideTitle?: boolean\n textboxPositionOffset?: string // when embedded in a form, the textbox (form) stuck to the bottom may need to be offset due to container padding (dialog content for example!)\n /* optional session context for the agent session */\n sessionContext?: GridAgentSessionContext\n /* The current session, if state is lifted out of this component */\n externalSession?: AgentSession\n /* A callback invoked to bootstrap the current session, if state is to be lifted out of this component */\n setExternalSession?: (s: AgentSession | undefined) => void\n /* The current chat history, if state is lifted out of this component */\n externalChatState?: ChatState\n // default access level for the agent session.\n defaultAgentAccessLevel?: AgentAccessLevel\n // Whether to show the access level menu for the agent session.\n showAccessLevelMenu?: boolean\n /**\n * Optional callback invoked once when a chat response is received from the server.\n * Use this for side effects such as navigation based on the response content.\n * Called in the mutation onSuccess handler so it runs exactly once per response.\n */\n onChatResponse?: (responseText: string) => void\n /** Optional list of prompt suggestions shown as clickable pills above the text input */\n suggestedPrompts?: string[]\n /** Optional custom avatar for the chatbot agent */\n agentAvatar?: React.ReactNode\n /**\n * Whether to allow the user to attach local files to their chat message.\n * @default false\n */\n allowAttachments?: boolean\n}\n\nexport function SynapseChat({\n initialMessage,\n agentRegistrationId,\n chatbotName = 'SynapseChat',\n variant = 'default',\n agentAvatar,\n hideTitle = false,\n textboxPositionOffset = '0px',\n sessionContext,\n externalSession,\n setExternalSession,\n externalChatState,\n showAccessLevelMenu = true,\n onChatResponse,\n suggestedPrompts,\n allowAttachments = false,\n}: SynapseChatProps) {\n const { accessToken } = useSynapseContext()\n const { userId } = useApplicationSessionContext()\n\n const baseDisclaimerText = chatbotName + ' can make mistakes'\n\n const resolvedAgentAvatar =\n agentAvatar ?? (variant === 'curie' ? CURIE_AVATAR : DEFAULT_AVATAR)\n\n const userAvatar = (\n <UserCard ownerId={userId} size=\"AVATAR\" avatarSize=\"MEDIUM\" />\n )\n const [localAgentSession, setLocalAgentSession] = useState<AgentSession>()\n const agentSession = externalSession ?? localAgentSession\n const setAgentSession = setExternalSession ?? setLocalAgentSession\n\n const { mutate: createAgentSession, error: createAgentSessionError } =\n useCreateAgentSession({\n onSuccess: newAgentSession => setAgentSession(newAgentSession),\n })\n\n const { mutate: updateAgentSession } = useUpdateAgentSession({\n onSuccess: updatedAgentSession => setAgentSession(updatedAgentSession),\n onError: err =>\n displayToast(\n `Unable to update the agent session: ${err.message}`,\n 'danger',\n ),\n })\n const [agentAccessLevel, setAgentAccessLevel] = useState<AgentAccessLevel>(\n sessionContext\n ? AgentAccessLevel.WRITE_YOUR_PRIVATE_DATA\n : AgentAccessLevel.PUBLICLY_ACCESSIBLE,\n )\n\n const internalChatState = useChatState(agentSession, onChatResponse)\n const chatState = externalChatState ?? internalChatState\n const { interactions, isAwaitingResponse, sendChat } = chatState\n\n const showGreeting = variant === 'curie' && interactions.length === 0\n\n const curieAccessLevelSuffix =\n variant === 'curie' ? CURIE_ACCESS_LEVEL_SUFFIX[agentAccessLevel] : ''\n const disclaimerText = baseDisclaimerText + curieAccessLevelSuffix\n\n // Only interactions added after this component instance mounted should play the entry\n // animation. Callers may lift state so history survives a `Dialog` closing, but the\n // `Dialog` unmounts its children, so every reopen would otherwise re-animate the whole\n // conversation.\n const presentAtMountRef = useRef<Set<string> | undefined>(undefined)\n if (presentAtMountRef.current === undefined) {\n presentAtMountRef.current = new Set(interactions.map(i => i.id))\n }\n const presentAtMount = presentAtMountRef.current\n\n // Keep track of the text that the user is currently typing into the textfield\n const [userChatTextfieldValue, setUserChatTextfieldValue] = useState('')\n const [initialMessageProcessed, setInitialMessageProcessed] = useState(false)\n\n // A copy of the attachments sent with the last interaction, so it can still show rich\n // (name/type) chips after ChatInputArea has cleared its own attachment state. This is passed to\n // the last interaction for its entire lifetime -- sent, then processing, then completed -- as a\n // fallback filename source, since the request body (FileHandleAssociation) never carries a\n // filename and the server-resolved filename (attachmentStatuses) only arrives once the job\n // completes. It's simply overwritten on the next send.\n const [lastSentAttachments, setLastSentAttachments] = useState<\n ChatAttachment[]\n >([])\n\n // Restore chat session history, if exists.\n // TODO: currently only a single page is restored. Add support for multiple pages (and detect the user scrolling up to restore the next page of results older)\n // const {\n // data: sessionHistoryInfiniteData,\n // } = //, hasNextPage: hasMoreSessionHistory, fetchNextPage: fetchNextSessionHistoryPage, isLoading: isSessionHistoryLoading } =\n // useGetAgentChatSessionHistoryInfinite(\n // {\n // sessionId: agentSession?.sessionId,\n // },\n // {\n // enabled: !!agentSession,\n // },\n // )\n\n // const sessionHistory = useMemo(\n // () =>\n // sessionHistoryInfiniteData?.pages\n // .flatMap(page => page.page)\n // /* Note: session history is ordered from most recent to least recent in each page, so reverse the order when restoring the chat interface */\n // .reverse() ?? [],\n // [sessionHistoryInfiniteData],\n // )\n\n useEffect(() => {\n // on mount, create a new agent session!\n if (createAgentSession && !agentSession) {\n createAgentSession({\n agentAccessLevel,\n agentRegistrationId,\n sessionContext,\n })\n }\n }, [\n createAgentSession,\n agentSession,\n accessToken,\n sessionContext,\n agentAccessLevel,\n agentRegistrationId,\n ])\n\n useEffect(() => {\n // on mount, resolve the initial message chat interaction (if set)\n if (agentSession && initialMessage && !initialMessageProcessed) {\n sendChat(initialMessage)\n setInitialMessageProcessed(true)\n }\n }, [agentSession, initialMessage, initialMessageProcessed, sendChat])\n\n const handleSend = (message: string, attachments: ChatAttachment[]) => {\n sendChat(\n message,\n attachments.length\n ? attachments.map(attachment => ({\n fileHandleId: attachment.fileHandleId,\n // The backend short-circuits the FileHandleAssociation auth check for a user's own\n // uploaded file handle, so associateObjectId/associateObjectType are not totally\n // accurate here. FileHandleAssociateType has no dedicated value for \"the uploader's\n // own bare file handle\", so this stubs associateObjectId to the fileHandleId itself\n // and the FileEntity associate type, which supports the short-circuit path.\n associateObjectId: attachment.fileHandleId,\n associateObjectType: FileHandleAssociateType.FileEntity,\n }))\n : undefined,\n )\n setUserChatTextfieldValue('')\n setLastSentAttachments(attachments)\n }\n\n if (createAgentSessionError) {\n return (\n <Alert severity={'error'} sx={{ my: 2 }}>\n {createAgentSessionError.reason}\n </Alert>\n )\n }\n\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: variant === 'curie' ? 'flex-start' : 'space-between',\n gap: variant === 'curie' ? '20px' : '0',\n maxWidth: '1100px',\n mx: 'auto',\n height: '100%',\n }}\n >\n {!hideTitle && (\n <Typography\n variant=\"headline1\"\n sx={{\n p: '20px',\n borderBottom: '1px solid',\n borderColor: 'grey.300',\n position: 'sticky',\n top: '0px',\n backgroundColor: 'white',\n zIndex: 1,\n }}\n >\n {chatbotName}\n </Typography>\n )}\n {showAccessLevelMenu && variant !== 'curie' && (\n <AccessLevelMenu\n initAccessLevel={agentAccessLevel}\n onChange={newAccessLevel => {\n setAgentAccessLevel(newAccessLevel)\n updateAgentSession({\n agentAccessLevel: newAccessLevel,\n sessionId: agentSession!.sessionId!,\n })\n }}\n />\n )}\n {!agentSession && <SkeletonParagraph numRows={10} />}\n {agentSession && (\n <Box\n sx={{\n flexGrow: 1,\n overflowY: 'auto',\n mb: variant === 'curie' ? 0 : 2,\n }}\n >\n <List\n sx={{\n flex: 1,\n overflowY: 'auto',\n pt: '20px',\n ...(variant === 'curie' && { pt: 0, pb: 0, gap: '20px' }),\n display: 'flex',\n flexDirection: 'column',\n ...(showGreeting && {\n minHeight: '100%',\n justifyContent: 'flex-end',\n }),\n }}\n >\n {/* {sessionHistory &&\n sessionHistory.map((interaction, index) => {\n return (\n <SynapseChatInteraction\n key={index}\n userMessage={interaction.usersRequestText}\n chatResponseText={interaction.agentResponseText}\n />\n )\n })} */}\n {showGreeting && (\n <ListItem\n sx={{\n display: 'grid',\n gridTemplateColumns: '50px auto',\n columnGap: '16px',\n justifyItems: 'start',\n alignItems: 'start',\n p: 0,\n }}\n >\n {resolvedAgentAvatar}\n <Typography sx={{ justifySelf: 'start', mt: '14px' }}>\n {CURIE_GREETING}\n </Typography>\n </ListItem>\n )}\n {interactions.map((interaction, index) => {\n const isLast = index === interactions.length - 1\n return (\n <SynapseChatMessage\n agentAvatar={resolvedAgentAvatar}\n userAvatar={userAvatar}\n key={interaction.id}\n userMessage={interaction.userMessage}\n chatJobId={interaction.jobId}\n showLoadingIcon={variant !== 'curie'}\n onSendChat={sendChat}\n scrollIntoView={isLast}\n animateEntry={!presentAtMount.has(interaction.id)}\n isAwaitingResponse={isAwaitingResponse}\n pendingAttachments={\n // Only one interaction can be in flight at a time (the composer is disabled\n // while isAwaitingResponse), so lastSentAttachments always corresponds to\n // whichever interaction is last.\n isLast ? lastSentAttachments : undefined\n }\n />\n )\n })}\n </List>\n </Box>\n )}\n <Box\n sx={{\n position: 'sticky',\n bottom: variant === 'curie' ? '0px' : textboxPositionOffset,\n backgroundColor: 'white',\n }}\n >\n {suggestedPrompts &&\n suggestedPrompts.length > 0 &&\n interactions.length === 0 && (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ pt: '8px', flexWrap: 'wrap', gap: 1 }}\n >\n {suggestedPrompts.map(prompt => (\n <Chip\n key={prompt}\n label={prompt}\n variant=\"outlined\"\n onClick={() => setUserChatTextfieldValue(prompt)}\n disabled={!agentSession}\n sx={{ cursor: 'pointer' }}\n />\n ))}\n </Stack>\n )}\n <Box sx={{ mt: '5px' }}>\n <ChatInputArea\n value={userChatTextfieldValue}\n onValueChange={setUserChatTextfieldValue}\n onSend={handleSend}\n placeholder={\n variant === 'curie' ? 'Ask anything' : `Message ${chatbotName}`\n }\n disabled={!agentSession || isAwaitingResponse}\n allowAttachments={allowAttachments}\n />\n </Box>\n </Box>\n <Typography variant=\"smallText1\" sx={{ pt: '8px', textAlign: 'center' }}>\n {disclaimerText}\n </Typography>\n </Box>\n )\n}\n\nexport default SynapseChat\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SynapseChat.js","names":[],"sources":["../../../src/components/SynapseChat/SynapseChat.tsx"],"sourcesContent":["import { ChatState, useChatState } from '@/components/SynapseChat/useChatState'\nimport {\n useCreateAgentSession,\n useUpdateAgentSession,\n} from '@/synapse-queries/chat/useChat'\nimport { useSynapseContext } from '@/utils'\nimport {\n Alert,\n Box,\n Chip,\n List,\n ListItem,\n Stack,\n Typography,\n} from '@mui/material'\nimport {\n AgentSession,\n FileHandleAssociateType,\n GridAgentSessionContext,\n} from '@sage-bionetworks/synapse-client'\nimport { AgentAccessLevel } from '@sage-bionetworks/synapse-types'\nimport { useEffect, useRef, useState } from 'react'\nimport { SkeletonParagraph } from '../Skeleton'\nimport { displayToast } from '../ToastMessage'\nimport AccessLevelMenu from './AccessLevelMenu'\nimport { ChatAttachment } from './utils/types'\nimport { ChatInputArea } from './components/ChatInputArea/ChatInputArea'\nimport SynapseChatMessage from './SynapseChatMessage'\nimport { SmartToyTwoTone } from '@mui/icons-material'\nimport { UserCard } from '../UserCard/UserCard'\nimport { useApplicationSessionContext } from '@/utils/AppUtils'\nimport { ReactComponent as CurieAvatarHead } from '@/assets/illustrations/curie_avatar_head.svg'\n\nconst CURIE_GREETING = 'Hi! How can I help you today?'\n\nconst CURIE_ACCESS_LEVEL_SUFFIX: Record<AgentAccessLevel, string> = {\n [AgentAccessLevel.PUBLICLY_ACCESSIBLE]: ' and can only read public data.',\n [AgentAccessLevel.READ_YOUR_PRIVATE_DATA]:\n ' and can read your public and private data in Synapse on your behalf.',\n [AgentAccessLevel.WRITE_YOUR_PRIVATE_DATA]:\n ' and can read and write your public and private data in Synapse on your behalf.',\n}\n\nconst DEFAULT_AVATAR = (\n <Box\n sx={{\n p: '3px',\n borderRadius: '50%',\n borderStyle: 'solid',\n borderWidth: '1px',\n borderColor: 'grey.300',\n mt: '10px',\n height: '31px',\n }}\n >\n <SmartToyTwoTone sx={{ color: 'secondary.main' }} />\n </Box>\n)\n\nconst CURIE_AVATAR = (\n <Box\n sx={{\n mt: '10px',\n height: '30px',\n width: '30px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <CurieAvatarHead />\n </Box>\n)\n\nexport type SynapseChatProps = {\n initialMessage?: string //optional initial message\n agentRegistrationId?: string // if provided, use this agent\n chatbotName?: string // optional name of this chatbot agent\n variant?: 'default' | 'curie'\n hideTitle?: boolean\n textboxPositionOffset?: string // when embedded in a form, the textbox (form) stuck to the bottom may need to be offset due to container padding (dialog content for example!)\n /* optional session context for the agent session */\n sessionContext?: GridAgentSessionContext\n /* The current session, if state is lifted out of this component */\n externalSession?: AgentSession\n /* A callback invoked to bootstrap the current session, if state is to be lifted out of this component */\n setExternalSession?: (s: AgentSession | undefined) => void\n /* The current chat history, if state is lifted out of this component */\n externalChatState?: ChatState\n // default access level for the agent session.\n defaultAgentAccessLevel?: AgentAccessLevel\n // Whether to show the access level menu for the agent session.\n showAccessLevelMenu?: boolean\n /**\n * Optional callback invoked once when a chat response is received from the server.\n * Use this for side effects such as navigation based on the response content.\n * Called in the mutation onSuccess handler so it runs exactly once per response.\n */\n onChatResponse?: (responseText: string) => void\n /** Optional list of prompt suggestions shown as clickable pills above the text input */\n suggestedPrompts?: string[]\n /** Optional custom avatar for the chatbot agent */\n agentAvatar?: React.ReactNode\n /**\n * Whether to allow the user to attach local files to their chat message.\n * @default false\n */\n allowAttachments?: boolean\n /**\n * Invoked when creating the agent session fails because the current (anonymous) user is not\n * authorized to start a session with this agent. Callers should use this to prompt the user to\n * log in. When omitted, the session creation error is shown inline instead.\n */\n onSessionCreationUnauthenticated?: () => void\n}\n\nexport function SynapseChat({\n initialMessage,\n agentRegistrationId,\n chatbotName = 'SynapseChat',\n variant = 'default',\n agentAvatar,\n hideTitle = false,\n textboxPositionOffset = '0px',\n sessionContext,\n externalSession,\n setExternalSession,\n externalChatState,\n showAccessLevelMenu = true,\n onChatResponse,\n suggestedPrompts,\n allowAttachments = false,\n onSessionCreationUnauthenticated,\n}: SynapseChatProps) {\n const { accessToken, isAuthenticated } = useSynapseContext()\n const { userId } = useApplicationSessionContext()\n\n const baseDisclaimerText = chatbotName + ' can make mistakes'\n\n const resolvedAgentAvatar =\n agentAvatar ?? (variant === 'curie' ? CURIE_AVATAR : DEFAULT_AVATAR)\n\n const userAvatar = (\n <UserCard ownerId={userId} size=\"AVATAR\" avatarSize=\"MEDIUM\" />\n )\n const [localAgentSession, setLocalAgentSession] = useState<AgentSession>()\n const agentSession = externalSession ?? localAgentSession\n const setAgentSession = setExternalSession ?? setLocalAgentSession\n\n const { mutate: createAgentSession, error: createAgentSessionError } =\n useCreateAgentSession({\n onSuccess: newAgentSession => setAgentSession(newAgentSession),\n onError: err => {\n // A registration that the ACT has not opened to anonymous chat rejects an anonymous\n // session with a 401/403. Defer to the caller to prompt the user to log in.\n if (!isAuthenticated && (err.status === 401 || err.status === 403)) {\n onSessionCreationUnauthenticated?.()\n }\n },\n })\n\n const { mutate: updateAgentSession } = useUpdateAgentSession({\n onSuccess: updatedAgentSession => setAgentSession(updatedAgentSession),\n onError: err =>\n displayToast(\n `Unable to update the agent session: ${err.message}`,\n 'danger',\n ),\n })\n const [agentAccessLevel, setAgentAccessLevel] = useState<AgentAccessLevel>(\n sessionContext\n ? AgentAccessLevel.WRITE_YOUR_PRIVATE_DATA\n : AgentAccessLevel.PUBLICLY_ACCESSIBLE,\n )\n\n const internalChatState = useChatState(agentSession, onChatResponse)\n const chatState = externalChatState ?? internalChatState\n const { interactions, isAwaitingResponse, sendChat } = chatState\n\n const showGreeting = variant === 'curie' && interactions.length === 0\n\n const curieAccessLevelSuffix =\n variant === 'curie' ? CURIE_ACCESS_LEVEL_SUFFIX[agentAccessLevel] : ''\n const disclaimerText = baseDisclaimerText + curieAccessLevelSuffix\n\n // Only interactions added after this component instance mounted should play the entry\n // animation. Callers may lift state so history survives a `Dialog` closing, but the\n // `Dialog` unmounts its children, so every reopen would otherwise re-animate the whole\n // conversation.\n const presentAtMountRef = useRef<Set<string> | undefined>(undefined)\n if (presentAtMountRef.current === undefined) {\n presentAtMountRef.current = new Set(interactions.map(i => i.id))\n }\n const presentAtMount = presentAtMountRef.current\n\n // Keep track of the text that the user is currently typing into the textfield\n const [userChatTextfieldValue, setUserChatTextfieldValue] = useState('')\n const [initialMessageProcessed, setInitialMessageProcessed] = useState(false)\n\n // A copy of the attachments sent with the last interaction, so it can still show rich\n // (name/type) chips after ChatInputArea has cleared its own attachment state. This is passed to\n // the last interaction for its entire lifetime -- sent, then processing, then completed -- as a\n // fallback filename source, since the request body (FileHandleAssociation) never carries a\n // filename and the server-resolved filename (attachmentStatuses) only arrives once the job\n // completes. It's simply overwritten on the next send.\n const [lastSentAttachments, setLastSentAttachments] = useState<\n ChatAttachment[]\n >([])\n\n // Restore chat session history, if exists.\n // TODO: currently only a single page is restored. Add support for multiple pages (and detect the user scrolling up to restore the next page of results older)\n // const {\n // data: sessionHistoryInfiniteData,\n // } = //, hasNextPage: hasMoreSessionHistory, fetchNextPage: fetchNextSessionHistoryPage, isLoading: isSessionHistoryLoading } =\n // useGetAgentChatSessionHistoryInfinite(\n // {\n // sessionId: agentSession?.sessionId,\n // },\n // {\n // enabled: !!agentSession,\n // },\n // )\n\n // const sessionHistory = useMemo(\n // () =>\n // sessionHistoryInfiniteData?.pages\n // .flatMap(page => page.page)\n // /* Note: session history is ordered from most recent to least recent in each page, so reverse the order when restoring the chat interface */\n // .reverse() ?? [],\n // [sessionHistoryInfiniteData],\n // )\n\n useEffect(() => {\n // on mount, create a new agent session!\n if (createAgentSession && !agentSession) {\n createAgentSession({\n agentAccessLevel,\n agentRegistrationId,\n sessionContext,\n })\n }\n }, [\n createAgentSession,\n agentSession,\n accessToken,\n sessionContext,\n agentAccessLevel,\n agentRegistrationId,\n ])\n\n useEffect(() => {\n // on mount, resolve the initial message chat interaction (if set)\n if (agentSession && initialMessage && !initialMessageProcessed) {\n sendChat(initialMessage)\n setInitialMessageProcessed(true)\n }\n }, [agentSession, initialMessage, initialMessageProcessed, sendChat])\n\n const handleSend = (message: string, attachments: ChatAttachment[]) => {\n sendChat(\n message,\n attachments.length\n ? attachments.map(attachment => ({\n fileHandleId: attachment.fileHandleId,\n // The backend short-circuits the FileHandleAssociation auth check for a user's own\n // uploaded file handle, so associateObjectId/associateObjectType are not totally\n // accurate here. FileHandleAssociateType has no dedicated value for \"the uploader's\n // own bare file handle\", so this stubs associateObjectId to the fileHandleId itself\n // and the FileEntity associate type, which supports the short-circuit path.\n associateObjectId: attachment.fileHandleId,\n associateObjectType: FileHandleAssociateType.FileEntity,\n }))\n : undefined,\n )\n setUserChatTextfieldValue('')\n setLastSentAttachments(attachments)\n }\n\n if (createAgentSessionError) {\n // When an anonymous user can't start a session, the caller is redirecting them to log in, so\n // suppress the inline error in favor of that flow.\n const deferredToLogin =\n !isAuthenticated &&\n !!onSessionCreationUnauthenticated &&\n (createAgentSessionError.status === 401 ||\n createAgentSessionError.status === 403)\n if (!deferredToLogin) {\n return (\n <Alert severity={'error'} sx={{ my: 2 }}>\n {createAgentSessionError.reason}\n </Alert>\n )\n }\n }\n\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: variant === 'curie' ? 'flex-start' : 'space-between',\n gap: variant === 'curie' ? '20px' : '0',\n maxWidth: '1100px',\n mx: 'auto',\n height: '100%',\n }}\n >\n {!hideTitle && (\n <Typography\n variant=\"headline1\"\n sx={{\n p: '20px',\n borderBottom: '1px solid',\n borderColor: 'grey.300',\n position: 'sticky',\n top: '0px',\n backgroundColor: 'white',\n zIndex: 1,\n }}\n >\n {chatbotName}\n </Typography>\n )}\n {showAccessLevelMenu && variant !== 'curie' && isAuthenticated && (\n <AccessLevelMenu\n initAccessLevel={agentAccessLevel}\n onChange={newAccessLevel => {\n setAgentAccessLevel(newAccessLevel)\n updateAgentSession({\n agentAccessLevel: newAccessLevel,\n sessionId: agentSession!.sessionId!,\n })\n }}\n />\n )}\n {!agentSession && <SkeletonParagraph numRows={10} />}\n {agentSession && (\n <Box\n sx={{\n flexGrow: 1,\n overflowY: 'auto',\n mb: variant === 'curie' ? 0 : 2,\n }}\n >\n <List\n sx={{\n flex: 1,\n overflowY: 'auto',\n pt: '20px',\n ...(variant === 'curie' && { pt: 0, pb: 0, gap: '20px' }),\n display: 'flex',\n flexDirection: 'column',\n ...(showGreeting && {\n minHeight: '100%',\n justifyContent: 'flex-end',\n }),\n }}\n >\n {/* {sessionHistory &&\n sessionHistory.map((interaction, index) => {\n return (\n <SynapseChatInteraction\n key={index}\n userMessage={interaction.usersRequestText}\n chatResponseText={interaction.agentResponseText}\n />\n )\n })} */}\n {showGreeting && (\n <ListItem\n sx={{\n display: 'grid',\n gridTemplateColumns: '50px auto',\n columnGap: '16px',\n justifyItems: 'start',\n alignItems: 'start',\n p: 0,\n }}\n >\n {resolvedAgentAvatar}\n <Typography sx={{ justifySelf: 'start', mt: '14px' }}>\n {CURIE_GREETING}\n </Typography>\n </ListItem>\n )}\n {interactions.map((interaction, index) => {\n const isLast = index === interactions.length - 1\n return (\n <SynapseChatMessage\n agentAvatar={resolvedAgentAvatar}\n userAvatar={userAvatar}\n key={interaction.id}\n userMessage={interaction.userMessage}\n chatJobId={interaction.jobId}\n showLoadingIcon={variant !== 'curie'}\n onSendChat={sendChat}\n scrollIntoView={isLast}\n animateEntry={!presentAtMount.has(interaction.id)}\n isAwaitingResponse={isAwaitingResponse}\n pendingAttachments={\n // Only one interaction can be in flight at a time (the composer is disabled\n // while isAwaitingResponse), so lastSentAttachments always corresponds to\n // whichever interaction is last.\n isLast ? lastSentAttachments : undefined\n }\n />\n )\n })}\n </List>\n </Box>\n )}\n <Box\n sx={{\n position: 'sticky',\n bottom: variant === 'curie' ? '0px' : textboxPositionOffset,\n backgroundColor: 'white',\n }}\n >\n {suggestedPrompts &&\n suggestedPrompts.length > 0 &&\n interactions.length === 0 && (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ pt: '8px', flexWrap: 'wrap', gap: 1 }}\n >\n {suggestedPrompts.map(prompt => (\n <Chip\n key={prompt}\n label={prompt}\n variant=\"outlined\"\n onClick={() => setUserChatTextfieldValue(prompt)}\n disabled={!agentSession}\n sx={{ cursor: 'pointer' }}\n />\n ))}\n </Stack>\n )}\n <Box sx={{ mt: '5px' }}>\n <ChatInputArea\n value={userChatTextfieldValue}\n onValueChange={setUserChatTextfieldValue}\n onSend={handleSend}\n placeholder={\n variant === 'curie' ? 'Ask anything' : `Message ${chatbotName}`\n }\n disabled={!agentSession || isAwaitingResponse}\n allowAttachments={allowAttachments}\n />\n </Box>\n </Box>\n <Typography variant=\"smallText1\" sx={{ pt: '8px', textAlign: 'center' }}>\n {disclaimerText}\n </Typography>\n </Box>\n )\n}\n\nexport default SynapseChat\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiCA,IAAM,KAAiB,iCAEjB,KAA8D;EACjE,EAAiB,sBAAsB;EACvC,EAAiB,yBAChB;EACD,EAAiB,0BAChB;AACJ,GAEM,KACJ,kBAAC,GAAD;CACE,IAAI;EACF,GAAG;EACH,cAAc;EACd,aAAa;EACb,aAAa;EACb,aAAa;EACb,IAAI;EACJ,QAAQ;CACV;WAEA,kBAAC,GAAD,EAAiB,IAAI,EAAE,OAAO,iBAAiB,EAAI,CAAA;AAChD,CAAA,GAGD,KACJ,kBAAC,GAAD;CACE,IAAI;EACF,IAAI;EACJ,QAAQ;EACR,OAAO;EACP,SAAS;EACT,YAAY;EACZ,gBAAgB;CAClB;WAEA,kBAAC,GAAD,CAAkB,CAAA;AACf,CAAA;AA6CP,SAAgB,EAAY,EAC1B,mBACA,wBACA,iBAAc,eACd,aAAU,WACV,gBACA,eAAY,IACZ,2BAAwB,OACxB,mBACA,oBACA,uBACA,sBACA,yBAAsB,IACtB,mBACA,qBACA,sBAAmB,IACnB,uCACmB;CACnB,IAAM,EAAE,gBAAa,uBAAoB,EAAkB,GACrD,EAAE,cAAW,EAA6B,GAE1C,IAAqB,IAAc,sBAEnC,IACJ,MAAgB,MAAY,UAAU,KAAe,KAEjD,IACJ,kBAAC,IAAD;EAAU,SAAS;EAAQ,MAAK;EAAS,YAAW;CAAU,CAAA,GAE1D,CAAC,GAAmB,MAAwB,EAAuB,GACnE,IAAe,KAAmB,GAClC,IAAkB,KAAsB,IAExC,EAAE,QAAQ,GAAoB,OAAO,MACzC,EAAsB;EACpB,YAAW,MAAmB,EAAgB,CAAe;EAC7D,UAAS,MAAO;GAGd,AAAI,CAAC,MAAoB,EAAI,WAAW,OAAO,EAAI,WAAW,QAC5D,IAAmC;EAEvC;CACF,CAAC,GAEG,EAAE,QAAQ,OAAuB,EAAsB;EAC3D,YAAW,MAAuB,EAAgB,CAAmB;EACrE,UAAS,MACP,EACE,uCAAuC,EAAI,WAC3C,QACF;CACJ,CAAC,GACK,CAAC,GAAkB,MAAuB,EAC9C,IACI,EAAiB,0BACjB,EAAiB,mBACvB,GAEM,KAAoB,EAAa,GAAc,CAAc,GAE7D,EAAE,iBAAc,uBAAoB,gBADxB,KAAqB,IAGjC,IAAe,MAAY,WAAW,EAAa,WAAW,GAI9D,KAAiB,KADrB,MAAY,UAAU,GAA0B,KAAoB,KAOhE,IAAoB,EAAgC,KAAA,CAAS;CACnE,AAAI,EAAkB,YAAY,KAAA,MAChC,EAAkB,UAAU,IAAI,IAAI,EAAa,KAAI,MAAK,EAAE,EAAE,CAAC;CAEjE,IAAM,KAAiB,EAAkB,SAGnC,CAAC,IAAwB,KAA6B,EAAS,EAAE,GACjE,CAAC,GAAyB,MAA8B,EAAS,EAAK,GAQtE,CAAC,IAAqB,MAA0B,EAEpD,CAAC,CAAC;CA2CJ,AAlBA,QAAgB;EAEd,AAAI,KAAsB,CAAC,KACzB,EAAmB;GACjB;GACA;GACA;EACF,CAAC;CAEL,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,GAED,QAAgB;EAEd,AAAI,KAAgB,KAAkB,CAAC,MACrC,EAAS,CAAc,GACvB,GAA2B,EAAI;CAEnC,GAAG;EAAC;EAAc;EAAgB;EAAyB;CAAQ,CAAC;CAEpE,IAAM,MAAc,GAAiB,MAAkC;EAiBrE,AAhBA,EACE,GACA,EAAY,SACR,EAAY,KAAI,OAAe;GAC7B,cAAc,EAAW;GAMzB,mBAAmB,EAAW;GAC9B,qBAAqB,GAAwB;EAC/C,EAAE,IACF,KAAA,CACN,GACA,EAA0B,EAAE,GAC5B,GAAuB,CAAW;CACpC;CAmBA,OAjBI,KAQE,EAJF,CAAC,KACC,MACD,EAAwB,WAAW,OAClC,EAAwB,WAAW,QAGnC,kBAAC,GAAD;EAAO,UAAU;EAAS,IAAI,EAAE,IAAI,EAAE;YACnC,EAAwB;CACpB,CAAA,IAMX,kBAAC,GAAD;EACE,IAAI;GACF,SAAS;GACT,eAAe;GACf,gBAAgB,MAAY,UAAU,eAAe;GACrD,KAAK,MAAY,UAAU,SAAS;GACpC,UAAU;GACV,IAAI;GACJ,QAAQ;EACV;YATF;GAWG,CAAC,KACA,kBAAC,GAAD;IACE,SAAQ;IACR,IAAI;KACF,GAAG;KACH,cAAc;KACd,aAAa;KACb,UAAU;KACV,KAAK;KACL,iBAAiB;KACjB,QAAQ;IACV;cAEC;GACS,CAAA;GAEb,KAAuB,MAAY,WAAW,KAC7C,kBAAC,IAAD;IACE,iBAAiB;IACjB,WAAU,MAAkB;KAE1B,AADA,GAAoB,CAAc,GAClC,GAAmB;MACjB,kBAAkB;MAClB,WAAW,EAAc;KAC3B,CAAC;IACH;GACD,CAAA;GAEF,CAAC,KAAgB,kBAAC,IAAD,EAAmB,SAAS,GAAK,CAAA;GAClD,KACC,kBAAC,GAAD;IACE,IAAI;KACF,UAAU;KACV,WAAW;KACX,IAAI,MAAY,UAAU,IAAI;IAChC;cAEA,kBAAC,GAAD;KACE,IAAI;MACF,MAAM;MACN,WAAW;MACX,IAAI;MACJ,GAAI,MAAY,WAAW;OAAE,IAAI;OAAG,IAAI;OAAG,KAAK;MAAO;MACvD,SAAS;MACT,eAAe;MACf,GAAI,KAAgB;OAClB,WAAW;OACX,gBAAgB;MAClB;KACF;eAZF,CAwBG,KACC,kBAAC,GAAD;MACE,IAAI;OACF,SAAS;OACT,qBAAqB;OACrB,WAAW;OACX,cAAc;OACd,YAAY;OACZ,GAAG;MACL;gBARF,CAUG,GACD,kBAAC,GAAD;OAAY,IAAI;QAAE,aAAa;QAAS,IAAI;OAAO;iBAChD;MACS,CAAA,CACJ;SAEX,EAAa,KAAK,GAAa,MAAU;MACxC,IAAM,IAAS,MAAU,EAAa,SAAS;MAC/C,OACE,kBAAC,IAAD;OACE,aAAa;OACD;OAEZ,aAAa,EAAY;OACzB,WAAW,EAAY;OACvB,iBAAiB,MAAY;OAC7B,YAAY;OACZ,gBAAgB;OAChB,cAAc,CAAC,GAAe,IAAI,EAAY,EAAE;OAC5B;OACpB,oBAIE,IAAS,KAAsB,KAAA;MAElC,GAdM,EAAY,EAclB;KAEL,CAAC,CACG;;GACH,CAAA;GAEP,kBAAC,GAAD;IACE,IAAI;KACF,UAAU;KACV,QAAQ,MAAY,UAAU,QAAQ;KACtC,iBAAiB;IACnB;cALF,CAOG,KACC,EAAiB,SAAS,KAC1B,EAAa,WAAW,KACtB,kBAAC,GAAD;KACE,WAAU;KACV,SAAS;KACT,IAAI;MAAE,IAAI;MAAO,UAAU;MAAQ,KAAK;KAAE;eAEzC,EAAiB,KAAI,MACpB,kBAAC,GAAD;MAEE,OAAO;MACP,SAAQ;MACR,eAAe,EAA0B,CAAM;MAC/C,UAAU,CAAC;MACX,IAAI,EAAE,QAAQ,UAAU;KACzB,GANM,CAMN,CACF;IACI,CAAA,GAEX,kBAAC,GAAD;KAAK,IAAI,EAAE,IAAI,MAAM;eACnB,kBAAC,IAAD;MACE,OAAO;MACP,eAAe;MACf,QAAQ;MACR,aACE,MAAY,UAAU,iBAAiB,WAAW;MAEpD,UAAU,CAAC,KAAgB;MACT;KACnB,CAAA;IACE,CAAA,CACF;;GACL,kBAAC,GAAD;IAAY,SAAQ;IAAa,IAAI;KAAE,IAAI;KAAO,WAAW;IAAS;cACnE;GACS,CAAA;EACT;;AAET"}
|
|
@@ -5,7 +5,9 @@ export type SynapsePortalChatDialogProps = SynapseChatProps & {
|
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
7
|
* A dialog that wraps SynapseChat with externally-controlled open/close state.
|
|
8
|
-
*
|
|
8
|
+
*
|
|
9
|
+
* Anonymous users are allowed to open the dialog: SynapseChat attempts to create a session, and if
|
|
10
|
+
* the agent is not open to anonymous chat, the user is redirected to log in.
|
|
9
11
|
*/
|
|
10
12
|
export declare function SynapsePortalChatDialog({ open, onClose, ...chatDialogProps }: SynapsePortalChatDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
11
13
|
export default SynapsePortalChatDialog;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapsePortalChatDialog.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseChat/SynapsePortalChatDialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SynapsePortalChatDialog.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseChat/SynapsePortalChatDialog.tsx"],"names":[],"mappings":"AAIA,OAAoB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAE7D,MAAM,MAAM,4BAA4B,GAAG,gBAAgB,GAAG;IAC5D,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,IAAI,EACJ,OAAO,EACP,GAAG,eAAe,EACnB,EAAE,4BAA4B,2CAyB9B;AAED,eAAe,uBAAuB,CAAA"}
|
|
@@ -1,21 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import t from "
|
|
3
|
-
import
|
|
1
|
+
import { storeRedirectURLForOneSageLoginAndGotoURL as e } from "../../utils/AppUtils/AppUtils.js";
|
|
2
|
+
import { useOneSageURL as t } from "../../utils/hooks/useOneSageURL.js";
|
|
3
|
+
import "../../utils/AppUtils/index.js";
|
|
4
|
+
import { SynapseChat as n } from "./SynapseChat.js";
|
|
5
|
+
import r from "../DraggableDialog/DraggableDialog.js";
|
|
6
|
+
import { persistPortalChatReopenIntent as i } from "./portalChatSessionStorage.js";
|
|
7
|
+
import { jsx as a } from "react/jsx-runtime";
|
|
4
8
|
//#region src/components/SynapseChat/SynapsePortalChatDialog.tsx
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
function o({ open: o, onClose: s, ...c }) {
|
|
10
|
+
let l = t();
|
|
11
|
+
return /* @__PURE__ */ a(r, {
|
|
12
|
+
open: o,
|
|
13
|
+
onClose: s,
|
|
14
|
+
title: c.chatbotName || "SynapseChat",
|
|
15
|
+
variant: c.variant,
|
|
16
|
+
children: /* @__PURE__ */ a(n, {
|
|
12
17
|
hideTitle: !0,
|
|
13
18
|
textboxPositionOffset: "16px",
|
|
14
|
-
|
|
19
|
+
onSessionCreationUnauthenticated: () => {
|
|
20
|
+
i({
|
|
21
|
+
variant: c.variant,
|
|
22
|
+
initialMessage: c.initialMessage
|
|
23
|
+
}), e(l.toString());
|
|
24
|
+
},
|
|
25
|
+
...c
|
|
15
26
|
})
|
|
16
|
-
},
|
|
27
|
+
}, c.variant);
|
|
17
28
|
}
|
|
18
29
|
//#endregion
|
|
19
|
-
export {
|
|
30
|
+
export { o as SynapsePortalChatDialog, o as default };
|
|
20
31
|
|
|
21
32
|
//# sourceMappingURL=SynapsePortalChatDialog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapsePortalChatDialog.js","names":[],"sources":["../../../src/components/SynapseChat/SynapsePortalChatDialog.tsx"],"sourcesContent":["import DraggableDialog from '../DraggableDialog/DraggableDialog'\nimport SynapseChat, { SynapseChatProps } from './SynapseChat'\n\nexport type SynapsePortalChatDialogProps = SynapseChatProps & {\n open: boolean\n onClose: () => void\n}\n\n/**\n * A dialog that wraps SynapseChat with externally-controlled open/close state.\n *
|
|
1
|
+
{"version":3,"file":"SynapsePortalChatDialog.js","names":[],"sources":["../../../src/components/SynapseChat/SynapsePortalChatDialog.tsx"],"sourcesContent":["import DraggableDialog from '../DraggableDialog/DraggableDialog'\nimport { storeRedirectURLForOneSageLoginAndGotoURL } from '@/utils/AppUtils'\nimport { useOneSageURL } from '@/utils/hooks/useOneSageURL'\nimport { persistPortalChatReopenIntent } from './portalChatSessionStorage'\nimport SynapseChat, { SynapseChatProps } from './SynapseChat'\n\nexport type SynapsePortalChatDialogProps = SynapseChatProps & {\n open: boolean\n onClose: () => void\n}\n\n/**\n * A dialog that wraps SynapseChat with externally-controlled open/close state.\n *\n * Anonymous users are allowed to open the dialog: SynapseChat attempts to create a session, and if\n * the agent is not open to anonymous chat, the user is redirected to log in.\n */\nexport function SynapsePortalChatDialog({\n open,\n onClose,\n ...chatDialogProps\n}: SynapsePortalChatDialogProps) {\n const oneSageUrl = useOneSageURL()\n return (\n <DraggableDialog\n key={chatDialogProps.variant}\n open={open}\n onClose={onClose}\n title={chatDialogProps.chatbotName || 'SynapseChat'}\n variant={chatDialogProps.variant}\n >\n <SynapseChat\n hideTitle={true}\n textboxPositionOffset=\"16px\"\n onSessionCreationUnauthenticated={() => {\n // Remember the chat was open so it can be reopened after the login round-trip.\n persistPortalChatReopenIntent({\n variant: chatDialogProps.variant,\n initialMessage: chatDialogProps.initialMessage,\n })\n storeRedirectURLForOneSageLoginAndGotoURL(oneSageUrl.toString())\n }}\n {...chatDialogProps}\n />\n </DraggableDialog>\n )\n}\n\nexport default SynapsePortalChatDialog\n"],"mappings":";;;;;;;;AAiBA,SAAgB,EAAwB,EACtC,SACA,YACA,GAAG,KAC4B;CAC/B,IAAM,IAAa,EAAc;CACjC,OACE,kBAAC,GAAD;EAEQ;EACG;EACT,OAAO,EAAgB,eAAe;EACtC,SAAS,EAAgB;YAEzB,kBAAC,GAAD;GACE,WAAW;GACX,uBAAsB;GACtB,wCAAwC;IAMtC,AAJA,EAA8B;KAC5B,SAAS,EAAgB;KACzB,gBAAgB,EAAgB;IAClC,CAAC,GACD,EAA0C,EAAW,SAAS,CAAC;GACjE;GACA,GAAI;EACL,CAAA;CACc,GAnBV,EAAgB,OAmBN;AAErB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persists, across an OAuth login round-trip, the intent to reopen the portal chat dialog.
|
|
3
|
+
*
|
|
4
|
+
* When an anonymous user opens the chat and is redirected to log in, the full-page navigation
|
|
5
|
+
* discards the dialog's open state. Storing the intent before the redirect lets the app reopen the
|
|
6
|
+
* dialog when the user returns authenticated.
|
|
7
|
+
*
|
|
8
|
+
* localStorage (not sessionStorage) is used because the login flow returns to the portal origin in a
|
|
9
|
+
* way that may not preserve the original tab's session (e.g. a fresh tab), and localStorage is shared
|
|
10
|
+
* across tabs of the same origin. The intent is consumed once and carries a short TTL so it can only
|
|
11
|
+
* reopen the chat as part of the immediate round-trip.
|
|
12
|
+
*/
|
|
13
|
+
export type PortalChatReopenIntent = {
|
|
14
|
+
variant?: 'default' | 'curie';
|
|
15
|
+
initialMessage?: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function persistPortalChatReopenIntent(intent: PortalChatReopenIntent): void;
|
|
18
|
+
/**
|
|
19
|
+
* Returns the stored reopen intent and removes it, so a given intent is only ever acted on once.
|
|
20
|
+
* Intents older than the TTL are discarded.
|
|
21
|
+
*/
|
|
22
|
+
export declare function consumePortalChatReopenIntent(): PortalChatReopenIntent | undefined;
|
|
23
|
+
//# sourceMappingURL=portalChatSessionStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portalChatSessionStorage.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseChat/portalChatSessionStorage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAOD,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,sBAAsB,QAO3E;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,IACzC,sBAAsB,GACtB,SAAS,CAkBZ"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/components/SynapseChat/portalChatSessionStorage.ts
|
|
2
|
+
var e = "portalChat.reopenAfterLogin", t = 3600 * 1e3;
|
|
3
|
+
function n(t) {
|
|
4
|
+
try {
|
|
5
|
+
let n = {
|
|
6
|
+
...t,
|
|
7
|
+
savedAt: Date.now()
|
|
8
|
+
};
|
|
9
|
+
localStorage.setItem(e, JSON.stringify(n));
|
|
10
|
+
} catch {}
|
|
11
|
+
}
|
|
12
|
+
function r() {
|
|
13
|
+
try {
|
|
14
|
+
let n = localStorage.getItem(e);
|
|
15
|
+
if (!n) return;
|
|
16
|
+
localStorage.removeItem(e);
|
|
17
|
+
let r = JSON.parse(n);
|
|
18
|
+
return typeof r.savedAt != "number" || Date.now() - r.savedAt > t ? void 0 : {
|
|
19
|
+
variant: r.variant,
|
|
20
|
+
initialMessage: r.initialMessage
|
|
21
|
+
};
|
|
22
|
+
} catch {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { r as consumePortalChatReopenIntent, n as persistPortalChatReopenIntent };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=portalChatSessionStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portalChatSessionStorage.js","names":[],"sources":["../../../src/components/SynapseChat/portalChatSessionStorage.ts"],"sourcesContent":["/**\n * Persists, across an OAuth login round-trip, the intent to reopen the portal chat dialog.\n *\n * When an anonymous user opens the chat and is redirected to log in, the full-page navigation\n * discards the dialog's open state. Storing the intent before the redirect lets the app reopen the\n * dialog when the user returns authenticated.\n *\n * localStorage (not sessionStorage) is used because the login flow returns to the portal origin in a\n * way that may not preserve the original tab's session (e.g. a fresh tab), and localStorage is shared\n * across tabs of the same origin. The intent is consumed once and carries a short TTL so it can only\n * reopen the chat as part of the immediate round-trip.\n */\n\nexport type PortalChatReopenIntent = {\n variant?: 'default' | 'curie'\n initialMessage?: string\n}\n\nconst STORAGE_KEY = 'portalChat.reopenAfterLogin'\nconst MAX_AGE_MS = 60 * 60 * 1000 // 1 hour, generous enough to cover login (incl. 2FA)\n\ntype StoredIntent = PortalChatReopenIntent & { savedAt: number }\n\nexport function persistPortalChatReopenIntent(intent: PortalChatReopenIntent) {\n try {\n const stored: StoredIntent = { ...intent, savedAt: Date.now() }\n localStorage.setItem(STORAGE_KEY, JSON.stringify(stored))\n } catch {\n // Storage may be unavailable (e.g. private browsing); reopening is best-effort.\n }\n}\n\n/**\n * Returns the stored reopen intent and removes it, so a given intent is only ever acted on once.\n * Intents older than the TTL are discarded.\n */\nexport function consumePortalChatReopenIntent():\n | PortalChatReopenIntent\n | undefined {\n try {\n const raw = localStorage.getItem(STORAGE_KEY)\n if (!raw) {\n return undefined\n }\n localStorage.removeItem(STORAGE_KEY)\n const stored = JSON.parse(raw) as StoredIntent\n if (\n typeof stored.savedAt !== 'number' ||\n Date.now() - stored.savedAt > MAX_AGE_MS\n ) {\n return undefined\n }\n return { variant: stored.variant, initialMessage: stored.initialMessage }\n } catch {\n return undefined\n }\n}\n"],"mappings":";AAkBA,IAAM,IAAc,+BACd,IAAa,OAAU;AAI7B,SAAgB,EAA8B,GAAgC;CAC5E,IAAI;EACF,IAAM,IAAuB;GAAE,GAAG;GAAQ,SAAS,KAAK,IAAI;EAAE;EAC9D,aAAa,QAAQ,GAAa,KAAK,UAAU,CAAM,CAAC;CAC1D,QAAQ,CAER;AACF;AAMA,SAAgB,IAEF;CACZ,IAAI;EACF,IAAM,IAAM,aAAa,QAAQ,CAAW;EAC5C,IAAI,CAAC,GACH;EAEF,aAAa,WAAW,CAAW;EACnC,IAAM,IAAS,KAAK,MAAM,CAAG;EAO7B,OALE,OAAO,EAAO,WAAY,YAC1B,KAAK,IAAI,IAAI,EAAO,UAAU,IAE9B,SAEK;GAAE,SAAS,EAAO;GAAS,gBAAgB,EAAO;EAAe;CAC1E,QAAQ;EACN;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.
|
|
1
|
+
._container_mn1du_1{background-color:#fff3;border-radius:9px;grid-template-columns:100%;justify-items:start;max-width:1300px;margin:auto;padding-top:0;padding-bottom:40px;display:grid}@media (width>=600px){._container_mn1du_1{grid-template-columns:50% 50%;padding-top:80px;padding-bottom:60px}}._item_mn1du_20{border-right:1px solid var(--synapse-gray-400);border-bottom:1px solid var(--synapse-gray-400);border-left:1px solid var(--synapse-gray-400);grid-template-columns:80% 20%;display:grid}._item_mn1du_20:first-child{border-top:1px solid var(--synapse-gray-400)}@media (width>=600px){._item_mn1du_20{border-top:none;border-left:none}._item_mn1du_20:nth-child(odd){border-left:1px solid var(--synapse-gray-400)}._item_mn1du_20:nth-child(-n+2){border-top:1px solid var(--synapse-gray-400)}}._item_mn1du_20{background-color:#ffffffe6;width:100%;padding:15px 0;text-decoration:none}._item_mn1du_20:hover{cursor:pointer;background-color:#e9f3fef2;text-decoration:none!important}._item_mn1du_20 ._itemTitle_mn1du_53{color:var(--synapse-gray-900);font-size:16px;font-weight:700}._item_mn1du_20 ._itemMeta_mn1du_58{color:var(--synapse-gray-700)}._adkpVariant_mn1du_62{grid-template-columns:100%;background-color:#0000!important}@media (width>=600px){._adkpVariant_mn1du_62{padding-top:0;padding-bottom:0}}._adkpVariant_mn1du_62 ._item_mn1du_20{border-left:1px solid var(--synapse-gray-400);border-top:none}._adkpVariant_mn1du_62 ._item_mn1du_20:first-child{border-top:1px solid var(--synapse-gray-400)}._adkpVariant_mn1du_62 ._item_mn1du_20:hover{background:linear-gradient(91deg,#7761b7 5.34%,#9067b6 24.31%,#816dc8 91.15%)}._adkpVariant_mn1du_62 ._item_mn1du_20:hover ._itemTitle_mn1du_53,._adkpVariant_mn1du_62 ._item_mn1du_20:hover ._itemMeta_mn1du_58,._adkpVariant_mn1du_62 ._item_mn1du_20:hover ._itemDescription_mn1du_84{color:#fff}._itemContent_mn1du_88{color:var(--synapse-gray-900);padding-left:15px;padding-right:10px}._itemAction_mn1du_94{place-self:start end;padding-right:15px}._chip_mn1du_100.MuiChip-root{border-radius:5px;height:24px}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import './HotdropsAndNews.css';var e = {
|
|
2
|
-
container: "
|
|
3
|
-
item: "
|
|
4
|
-
itemTitle: "
|
|
5
|
-
itemMeta: "
|
|
6
|
-
adkpVariant: "
|
|
7
|
-
itemDescription: "
|
|
8
|
-
itemContent: "
|
|
9
|
-
itemAction: "
|
|
10
|
-
chip: "
|
|
2
|
+
container: "_container_mn1du_1",
|
|
3
|
+
item: "_item_mn1du_20",
|
|
4
|
+
itemTitle: "_itemTitle_mn1du_53",
|
|
5
|
+
itemMeta: "_itemMeta_mn1du_58",
|
|
6
|
+
adkpVariant: "_adkpVariant_mn1du_62",
|
|
7
|
+
itemDescription: "_itemDescription_mn1du_84",
|
|
8
|
+
itemContent: "_itemContent_mn1du_88",
|
|
9
|
+
itemAction: "_itemAction_mn1du_94",
|
|
10
|
+
chip: "_chip_mn1du_100"
|
|
11
11
|
};
|
|
12
12
|
//#endregion
|
|
13
13
|
export { e as default };
|