-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
520 - client Update logic around connected user table and detail sheet
- Loading branch information
Showing
11 changed files
with
553 additions
and
409 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 0 additions & 25 deletions
25
client/src/pages/embedded/connected-users/components/ConnectedUserSheet.tsx
This file was deleted.
Oops, something went wrong.
383 changes: 0 additions & 383 deletions
383
client/src/pages/embedded/connected-users/components/ConnectedUserSheetPanel.tsx
This file was deleted.
Oops, something went wrong.
36 changes: 36 additions & 0 deletions
36
...src/pages/embedded/connected-users/components/connected-user-sheet/ConnectedUserSheet.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import {Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle} from '@/components/ui/sheet'; | ||
import ConnectedUserSheetPanel from '@/pages/embedded/connected-users/components/connected-user-sheet/ConnectedUserSheetPanel'; | ||
import ConnectedUserSheetTitle from '@/pages/embedded/connected-users/components/connected-user-sheet/ConnectedUserSheetTitle'; | ||
import useConnectedUserSheetStore from '@/pages/embedded/connected-users/stores/useConnectedUserSheetStore'; | ||
import {useGetConnectedUserQuery} from '@/shared/queries/embedded/connectedUsers.queries'; | ||
|
||
const ConnectedUserSheet = () => { | ||
const {connectedUserId, connectedUserSheetOpen, setConnectedUserSheetOpen} = useConnectedUserSheetStore(); | ||
|
||
const {data: connectedUser, isLoading: connectedUserLoading} = useGetConnectedUserQuery( | ||
connectedUserId, | ||
connectedUserSheetOpen | ||
); | ||
|
||
return ( | ||
<Sheet onOpenChange={() => setConnectedUserSheetOpen(!connectedUserSheetOpen)} open={connectedUserSheetOpen}> | ||
<SheetContent className="flex w-11/12 flex-col gap-0 p-0 sm:max-w-screen-md"> | ||
<SheetHeader className="p-4"> | ||
<SheetTitle className="flex justify-between"> | ||
{connectedUser && <ConnectedUserSheetTitle connectedUser={connectedUser} />} | ||
</SheetTitle> | ||
|
||
<SheetDescription></SheetDescription> | ||
</SheetHeader> | ||
|
||
{connectedUserLoading ? ( | ||
<span>Loading...</span> | ||
) : ( | ||
connectedUser && <ConnectedUserSheetPanel connectedUser={connectedUser} /> | ||
)} | ||
</SheetContent> | ||
</Sheet> | ||
); | ||
}; | ||
|
||
export default ConnectedUserSheet; |
36 changes: 36 additions & 0 deletions
36
...ages/embedded/connected-users/components/connected-user-sheet/ConnectedUserSheetPanel.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import ConnectedUserSheetPanelIntegrations from '@/pages/embedded/connected-users/components/connected-user-sheet/ConnectedUserSheetPanelIntegrations'; | ||
import ConnectedUserSheetPanelProfile from '@/pages/embedded/connected-users/components/connected-user-sheet/ConnectedUserSheetPanelProfile'; | ||
import {ConnectedUser} from '@/shared/middleware/embedded/connected-user'; | ||
|
||
interface ConnectedUserSheetPanelProps { | ||
connectedUser: ConnectedUser; | ||
} | ||
|
||
const ConnectedUserSheetPanel = ({connectedUser}: ConnectedUserSheetPanelProps) => { | ||
return ( | ||
<div className="flex w-full flex-col gap-4 px-2 pb-4"> | ||
<div className="flex w-full flex-col space-x-4"> | ||
<div className="w-full space-y-10"> | ||
<div className="w-full space-y-2 px-2"> | ||
<div className="text-base font-semibold">Profile</div> | ||
|
||
<ConnectedUserSheetPanelProfile connectedUser={connectedUser} /> | ||
</div> | ||
|
||
<div className="w-full space-y-2"> | ||
<div className="px-2 text-base font-semibold">Integrations</div> | ||
|
||
{connectedUser.integrationInstances && ( | ||
<ConnectedUserSheetPanelIntegrations | ||
connectedUserId={connectedUser.id!} | ||
connectedUserIntegrationInstances={connectedUser.integrationInstances} | ||
/> | ||
)} | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ConnectedUserSheetPanel; |
169 changes: 169 additions & 0 deletions
169
...ed/connected-users/components/connected-user-sheet/ConnectedUserSheetPanelIntegration.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
import {Badge} from '@/components/ui/badge'; | ||
import {Button} from '@/components/ui/button'; | ||
import {Collapsible, CollapsibleContent, CollapsibleTrigger} from '@/components/ui/collapsible'; | ||
import {DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger} from '@/components/ui/dropdown-menu'; | ||
import {Switch} from '@/components/ui/switch'; | ||
import {Tooltip, TooltipContent, TooltipTrigger} from '@/components/ui/tooltip'; | ||
import CredentialsStatus from '@/pages/embedded/connected-users/components/CredentialsStatus'; | ||
import ConnectedUserSheetPanelIntegrationWorkflows from '@/pages/embedded/connected-users/components/connected-user-sheet/ConnectedUserSheetPanelIntegrationWorkflows'; | ||
import {ConnectedUserIntegrationInstance} from '@/shared/middleware/embedded/connected-user'; | ||
import {ComponentDefinitionBasic} from '@/shared/middleware/platform/configuration'; | ||
import {useEnableIntegrationInstanceMutation} from '@/shared/mutations/embedded/integrationInstances.mutations'; | ||
import {ConnectedUserKeys} from '@/shared/queries/embedded/connectedUsers.queries'; | ||
import {useGetIntegrationInstanceConfigurationQuery} from '@/shared/queries/embedded/integrationInstanceConfigurations.queries'; | ||
import { | ||
IntegrationInstanceKeys, | ||
useGetIntegrationInstanceQuery, | ||
} from '@/shared/queries/embedded/integrationInstances.queries'; | ||
import {useGetIntegrationVersionWorkflowsQuery} from '@/shared/queries/embedded/integrationWorkflows.queries'; | ||
import {useQueryClient} from '@tanstack/react-query'; | ||
import {EllipsisVerticalIcon} from 'lucide-react'; | ||
import InlineSVG from 'react-inlinesvg'; | ||
import {twMerge} from 'tailwind-merge'; | ||
|
||
const ConnectedUserSheetPanelIntegration = ({ | ||
componentDefinition, | ||
componentDefinitions, | ||
connectedUserId, | ||
connectedUserIntegrationInstance, | ||
}: { | ||
componentDefinition: ComponentDefinitionBasic; | ||
connectedUserIntegrationInstance: ConnectedUserIntegrationInstance; | ||
connectedUserId: number; | ||
componentDefinitions: ComponentDefinitionBasic[]; | ||
}) => { | ||
const {data: workflows} = useGetIntegrationVersionWorkflowsQuery( | ||
connectedUserIntegrationInstance.integrationId!, | ||
connectedUserIntegrationInstance.integrationVersion! | ||
); | ||
|
||
const {data: integrationInstanceConfiguration} = useGetIntegrationInstanceConfigurationQuery( | ||
connectedUserIntegrationInstance.integrationInstanceConfigurationId! | ||
); | ||
|
||
const {data: integrationInstance} = useGetIntegrationInstanceQuery(connectedUserIntegrationInstance.id!); | ||
|
||
const queryClient = useQueryClient(); | ||
|
||
const enableIntegrationInstanceMutation = useEnableIntegrationInstanceMutation({ | ||
onSuccess: () => { | ||
queryClient.invalidateQueries({ | ||
queryKey: ConnectedUserKeys.connectedUser(connectedUserId), | ||
}); | ||
queryClient.invalidateQueries({ | ||
queryKey: IntegrationInstanceKeys.integrationInstance(connectedUserIntegrationInstance.id!), | ||
}); | ||
}, | ||
}); | ||
|
||
return ( | ||
<Collapsible key={connectedUserIntegrationInstance.id}> | ||
{componentDefinition && ( | ||
<div className="flex w-full items-center justify-between px-2 hover:bg-muted/50"> | ||
<CollapsibleTrigger className="flex-1 py-3"> | ||
<div className="flex flex-col items-start justify-center gap-y-2"> | ||
<div className="flex flex-1 items-center gap-1"> | ||
<InlineSVG | ||
className="size-5 flex-none" | ||
key={componentDefinition.name!} | ||
src={componentDefinition.icon!} | ||
/> | ||
|
||
<div | ||
className={twMerge( | ||
'text-base font-semibold flex items-center space-x-1', | ||
!connectedUserIntegrationInstance.enabled && 'text-muted-foreground' | ||
)} | ||
> | ||
<span>{componentDefinition.title}</span> | ||
</div> | ||
</div> | ||
|
||
<div className="flex gap-4"> | ||
<div className="flex items-center space-x-1 text-xs text-muted-foreground"> | ||
<CredentialsStatus | ||
enabled={connectedUserIntegrationInstance.credentialStatus === 'VALID'} | ||
/> | ||
|
||
<span>{`Account ${connectedUserIntegrationInstance.credentialStatus === 'VALID' ? 'Connected' : 'Errors'}`}</span> | ||
</div> | ||
|
||
<div className="flex items-center space-x-1"> | ||
{integrationInstance && ( | ||
<div className="group flex text-xs font-semibold text-muted-foreground"> | ||
{workflows?.length === 1 | ||
? `${workflows?.length} workflow` | ||
: `${workflows?.length} workflows`} | ||
</div> | ||
)} | ||
</div> | ||
</div> | ||
</div> | ||
</CollapsibleTrigger> | ||
|
||
<div className="flex items-center gap-x-2"> | ||
<div className="flex items-center gap-x-4"> | ||
{integrationInstance && ( | ||
<Badge variant="secondary"> | ||
V{integrationInstance.integrationInstanceConfiguration?.integrationVersion} | ||
</Badge> | ||
)} | ||
|
||
<div className="flex min-w-52 flex-col items-end gap-y-2"> | ||
<Switch | ||
checked={connectedUserIntegrationInstance.enabled} | ||
disabled={!integrationInstance?.integrationInstanceConfiguration?.enabled} | ||
onCheckedChange={(value) => { | ||
enableIntegrationInstanceMutation.mutate({ | ||
enable: value, | ||
id: connectedUserIntegrationInstance.id!, | ||
}); | ||
}} | ||
/> | ||
|
||
<Tooltip> | ||
<TooltipTrigger className="flex items-center text-sm text-gray-500"> | ||
{integrationInstance && integrationInstance.lastExecutionDate ? ( | ||
<span className="text-xs"> | ||
{`Executed at ${integrationInstance.lastExecutionDate?.toLocaleDateString()} ${integrationInstance.lastExecutionDate?.toLocaleTimeString()}`} | ||
</span> | ||
) : ( | ||
<span className="text-xs">No executions</span> | ||
)} | ||
</TooltipTrigger> | ||
|
||
<TooltipContent>Last Execution Date</TooltipContent> | ||
</Tooltip> | ||
</div> | ||
</div> | ||
|
||
<DropdownMenu> | ||
<DropdownMenuTrigger asChild> | ||
<Button size="icon" variant="ghost"> | ||
<EllipsisVerticalIcon className="size-4 hover:cursor-pointer" /> | ||
</Button> | ||
</DropdownMenuTrigger> | ||
|
||
<DropdownMenuContent align="end"> | ||
<DropdownMenuItem className="text-destructive">Delete</DropdownMenuItem> | ||
</DropdownMenuContent> | ||
</DropdownMenu> | ||
</div> | ||
</div> | ||
)} | ||
|
||
<CollapsibleContent> | ||
{workflows && integrationInstance && integrationInstanceConfiguration && ( | ||
<ConnectedUserSheetPanelIntegrationWorkflows | ||
componentDefinitions={componentDefinitions} | ||
integrationInstance={integrationInstance} | ||
integrationInstanceConfiguration={integrationInstanceConfiguration} | ||
workflows={workflows} | ||
/> | ||
)} | ||
</CollapsibleContent> | ||
</Collapsible> | ||
); | ||
}; | ||
|
||
export default ConnectedUserSheetPanelIntegration; |
91 changes: 91 additions & 0 deletions
91
...cted-users/components/connected-user-sheet/ConnectedUserSheetPanelIntegrationWorkflow.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import {Button} from '@/components/ui/button'; | ||
import {DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger} from '@/components/ui/dropdown-menu'; | ||
import {Switch} from '@/components/ui/switch'; | ||
import {IntegrationInstance, IntegrationInstanceWorkflow, Workflow} from '@/shared/middleware/embedded/configuration'; | ||
import {ComponentDefinitionBasic} from '@/shared/middleware/platform/configuration'; | ||
import {useEnableIntegrationInstanceWorkflowMutation} from '@/shared/mutations/embedded/integrationInstanceWorkflows.mutations'; | ||
import {ConnectedUserKeys} from '@/shared/queries/embedded/connectedUsers.queries'; | ||
import {IntegrationInstanceKeys} from '@/shared/queries/embedded/integrationInstances.queries'; | ||
import {useQueryClient} from '@tanstack/react-query'; | ||
import {EllipsisVerticalIcon} from 'lucide-react'; | ||
import InlineSVG from 'react-inlinesvg'; | ||
|
||
const ConnectedUserSheetPanelIntegrationWorkflow = ({ | ||
componentDefinitions, | ||
integrationInstance, | ||
integrationInstanceWorkflow, | ||
workflow, | ||
}: { | ||
componentDefinitions: ComponentDefinitionBasic[]; | ||
integrationInstance: IntegrationInstance; | ||
integrationInstanceWorkflow?: IntegrationInstanceWorkflow; | ||
workflow: Workflow; | ||
}) => { | ||
const filteredComponentDefinitions = [ | ||
...(workflow.workflowTaskComponentNames ?? []), | ||
...(workflow.workflowTriggerComponentNames ?? []), | ||
].map((componentName) => { | ||
return componentDefinitions?.find((componentDefinition) => componentDefinition.name === componentName); | ||
}); | ||
|
||
const queryClient = useQueryClient(); | ||
|
||
const enableIntegrationInstanceWorkflowMutation = useEnableIntegrationInstanceWorkflowMutation({ | ||
onSuccess: () => { | ||
queryClient.invalidateQueries({ | ||
queryKey: ConnectedUserKeys.connectedUser(integrationInstance.connectedUserId!), | ||
}); | ||
queryClient.invalidateQueries({ | ||
queryKey: IntegrationInstanceKeys.integrationInstance(integrationInstance.id!), | ||
}); | ||
}, | ||
}); | ||
|
||
return ( | ||
<li className="flex items-center justify-between rounded-md p-2 py-1 hover:bg-gray-50" key={workflow.id}> | ||
<div className="text-sm font-semibold">{workflow.label}</div> | ||
|
||
<div> | ||
{filteredComponentDefinitions?.map((componentDefinition) => { | ||
return ( | ||
componentDefinition && ( | ||
<InlineSVG | ||
className="mr-2 size-6 flex-none" | ||
key={componentDefinition.name!} | ||
src={componentDefinition.icon!} | ||
/> | ||
) | ||
); | ||
})} | ||
</div> | ||
|
||
<div className="flex items-center space-x-1"> | ||
<Switch | ||
checked={integrationInstanceWorkflow?.enabled} | ||
disabled={integrationInstance.enabled} | ||
onCheckedChange={(value) => { | ||
enableIntegrationInstanceWorkflowMutation.mutate({ | ||
enable: value, | ||
id: integrationInstance.id!, | ||
workflowId: workflow.id!, | ||
}); | ||
}} | ||
/> | ||
|
||
<DropdownMenu> | ||
<DropdownMenuTrigger asChild> | ||
<Button size="icon" variant="ghost"> | ||
<EllipsisVerticalIcon className="size-4 hover:cursor-pointer" /> | ||
</Button> | ||
</DropdownMenuTrigger> | ||
|
||
<DropdownMenuContent align="end"> | ||
<DropdownMenuItem className="text-destructive">Delete</DropdownMenuItem> | ||
</DropdownMenuContent> | ||
</DropdownMenu> | ||
</div> | ||
</li> | ||
); | ||
}; | ||
|
||
export default ConnectedUserSheetPanelIntegrationWorkflow; |
Oops, something went wrong.