Skip to content

Commit

Permalink
Merge branch 'main' of github.com:l3vels/L3AGI
Browse files Browse the repository at this point in the history
  • Loading branch information
okradze committed Jan 9, 2024
2 parents 5f98bd7 + 13e6437 commit b1d20de
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 61 deletions.
2 changes: 0 additions & 2 deletions apps/server/controllers/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ def get_chats(
filter: Optional[List[str]] = Query([""]),
page: Optional[int] = 1,
per_page: Optional[int] = 1,
agent_type: Optional[AgentType] = None,
auth: UserAccount = Depends(authenticate_by_token_or_api_key),
) -> ChatListOutput:
"""
Expand All @@ -76,7 +75,6 @@ def get_chats(
db=db,
account=auth.account,
filter_list=filter,
agent_type=agent_type,
page=page,
per_page=per_page,
)
Expand Down
21 changes: 16 additions & 5 deletions apps/server/models/chat.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import uuid

from sqlalchemy import UUID, Boolean, Column, ForeignKey, Integer, String, or_
from sqlalchemy import (UUID, Boolean, Column, ForeignKey, Integer, String,
and_, func, or_)
from sqlalchemy.orm import Session, joinedload, relationship

from exceptions import ChatNotFoundException
Expand All @@ -13,6 +14,14 @@
from typings.chat import ChatInput, UpdateChatInput


def is_valid_uuid(string):
try:
uuid_obj = uuid.UUID(string)
return str(uuid_obj) == string
except ValueError:
return False


class ChatModel(BaseModel):
"""
Model representing a chat message.
Expand Down Expand Up @@ -213,12 +222,17 @@ def update_model_from_input(cls, chat_model: "ChatModel", chat_input: ChatInput)
setattr(chat_model, field, getattr(chat_input, field))

@classmethod
def get_chats(cls, db, account, filter_list, agent_type, page=1, per_page=10):
def get_chats(cls, db, account, filter_list, page=1, per_page=10):
offset = (page - 1) * per_page

filter_conditions = [
or_(
ChatModel.name.ilike(f"%{filter_string}%"),
AgentModel.name.ilike(f"%{filter_string}%"),
AgentModel.agent_type.ilike(f"%{filter_string}%"),
ChatModel.campaign_id == filter_string
if is_valid_uuid(filter_string)
else None,
)
for filter_string in filter_list
]
Expand Down Expand Up @@ -248,9 +262,6 @@ def get_chats(cls, db, account, filter_list, agent_type, page=1, per_page=10):
)
)

if agent_type is not None:
query = query.filter(AgentModel.agent_type == agent_type)

chats = query.offset(offset).limit(per_page).all()
total_count = query.count()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@ import {
type TableActionButtonsProp = {
onDeleteClick?: () => void
onEditClick?: () => void
customActions?: any
}

const TableActionButtons = ({ onDeleteClick, onEditClick }: TableActionButtonsProp) => {
const TableActionButtons = ({
onDeleteClick,
onEditClick,
customActions,
}: TableActionButtonsProp) => {
return (
<StyledTableButtons>
{onDeleteClick && (
Expand All @@ -33,6 +38,8 @@ const TableActionButtons = ({ onDeleteClick, onEditClick }: TableActionButtonsPr
ariaLabel='Edit'
/>
)}

{customActions && customActions}
</StyledTableButtons>
)
}
Expand Down
1 change: 1 addition & 0 deletions apps/ui/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
"enter-email": "Enter email...",
"enter-password": "Enter password...",
"expiration": "Expiration",
"filter": "Filter",
"failed-to-create-new-asset": "Failed to create new asset",
"failed-to-create-new-collection": "Failed to create new collection",
"failed-to-add-new-api-key": "Failed to Add new API key",
Expand Down
28 changes: 21 additions & 7 deletions apps/ui/src/pages/Sessions/Session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { useLocation, useNavigate } from 'react-router-dom'
import IconButton from 'share-ui/components/IconButton/IconButton'
import { Close } from 'share-ui/components/Icon/Icons'

import { useState } from 'react'
import { useEffect, useState } from 'react'
import { ButtonTertiary } from 'components/Button/Button'
import {
StyledNavigationChevronDown,
Expand All @@ -45,6 +45,8 @@ const Sessions = () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
selectedAgentNames,
setSelectedAgentNames,
setSelectedCampaign,
selectedCampaign,
startDate,
endDate,
filterByDateRange,
Expand All @@ -55,6 +57,7 @@ const Sessions = () => {
totalPages,
chatsLoading,
setSelectedAgentType,
selectedAgentType,
campaignOptions,
} = useSession()

Expand All @@ -64,20 +67,28 @@ const Sessions = () => {
const location = useLocation()
const urlParams = new URLSearchParams(location.search)
const sessionId = urlParams.get('chat')
const campaignId = urlParams.get('campaign')

const agentTypeOption = [
{ label: 'Chat based', value: 'text' },
{ label: 'Call based', value: 'voice' },
]

useEffect(() => {
if (campaignId && campaignOptions?.length > 0) {
const value = campaignOptions?.find((option: any) => option.value === campaignId)
if (value) setSelectedCampaign([value])
}
}, [campaignId, campaignOptions])

return (
<StyledSectionWrapper>
<StyledHeaderGroup className='header_group'>
<StyledTitleWrapper>
<StyledSectionTitle>{t('sessions')}</StyledSectionTitle>

<ButtonTertiary onClick={() => setShowFilter(!showFilter)} size={'xs'}>
Filter
{t('filter')}
{showFilter ? (
<StyledNavigationChevronUp size={14} />
) : (
Expand Down Expand Up @@ -105,7 +116,8 @@ const Sessions = () => {
placeholder='Agent'
label={''}
options={agentOptions}
onChange={(selectedValues: string[]) => setSelectedAgentNames(selectedValues)}
onChange={setSelectedAgentNames}
value={selectedAgentNames}
/>

{/* <StyledDateWrapper>
Expand All @@ -126,16 +138,18 @@ const Sessions = () => {
placeholder='Agent Type'
label={''}
options={agentTypeOption}
onChange={(value: any) => setSelectedAgentType(value)}
onChange={setSelectedAgentType}
value={selectedAgentType}
/>
{/*

<SessionDropdown
isMulti
placeholder='Campaign'
label={''}
options={campaignOptions}
// onChange={(selectedValues: string[]) => setSelectedAgentNames(selectedValues)}
/> */}
onChange={setSelectedCampaign}
value={selectedCampaign}
/>

{/* <StyledSessionDropdownWrapper>
<StyledSessionDropdown
Expand Down
52 changes: 19 additions & 33 deletions apps/ui/src/pages/Sessions/SessionDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState } from 'react'
import styled from 'styled-components'
import styled, { useTheme } from 'styled-components'
import Dropdown from 'share-ui/components/Dropdown/Dropdown'

import Typography from 'share-ui/components/typography/Typography'
Expand All @@ -11,6 +11,7 @@ type SessionDropdownProps = {
isMulti?: boolean
placeholder: string
onChange?: any
value: any
}

const SessionDropdown = ({
Expand All @@ -19,37 +20,24 @@ const SessionDropdown = ({
isMulti,
placeholder,
onChange,
value,
}: SessionDropdownProps) => {
const [selectedValue, setSelectedValue] = useState<string | string[] | null>(null)
const theme = useTheme()

const onChangeFunction = (option: any) => {
if (isMulti) {
setSelectedValue(option || []) // Ensure option is always an array
} else {
setSelectedValue(option?.value || null)
}

// Call the onChange prop
if (onChange) {
onChange(isMulti ? (option || []).map((opt: any) => opt.value) : option?.value)
}
}

const onOptionRemove = (removedValue: any) => {
if (isMulti && Array.isArray(selectedValue)) {
const newValues = selectedValue.filter(oldValue => oldValue !== removedValue)

setSelectedValue([...newValues])

// Call the onChange prop
if (onChange) {
onChange(newValues.map((value: any) => value.value))
}
}
const optionRemoveHandler = (item: any) => {
const newValues = value.filter((oldValues: any) => oldValues !== item)
onChange(newValues)
}

const OptionRenderer = ({ label }: { label: string }) => {
return <TypographyPrimary value={label} type={Typography.types.LABEL} size='medium' />
return (
<TypographyPrimary
value={label}
type={Typography.types.LABEL}
size='medium'
customColor={theme.typography.contentPrimary}
/>
)
}

return (
Expand All @@ -59,13 +47,11 @@ const SessionDropdown = ({
insideOverflow
multiline
size={Dropdown.size.MEDIUM}
value={selectedValue}
placeholder={
options?.find((item: any) => item.value === selectedValue)?.label || placeholder
}
value={value}
placeholder={value?.label || placeholder}
options={options}
onChange={onChangeFunction}
onOptionRemove={onOptionRemove}
onChange={onChange}
onOptionRemove={optionRemoveHandler}
OptionRenderer={OptionRenderer}
/>
</StyledWrapper>
Expand Down
2 changes: 1 addition & 1 deletion apps/ui/src/pages/Sessions/columnConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ const StyledDateWrapper = styled.div`
align-items: center;
gap: 12px;
`
const StyledOpenIcon = styled(Open)`
export const StyledOpenIcon = styled(Open)`
path {
fill: ${({ theme }) => theme.body.iconColor};
}
Expand Down
20 changes: 15 additions & 5 deletions apps/ui/src/pages/Sessions/useSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ type Chat = {

export const useSession = () => {
const [searchText, setSearchText] = useState('')
const [selectedAgentType, setSelectedAgentType] = useState<'voice' | 'text' | null>(null)
const [selectedAgentNames, setSelectedAgentNames] = useState<string[]>([])
const [selectedAgentType, setSelectedAgentType] = useState<any>(null)
const [selectedAgentNames, setSelectedAgentNames] = useState<any>([])
const [selectedCampaign, setSelectedCampaign] = useState<any>([])
// const [selectedCampaign, setSelectedCampaign] = useState<string | null>(null)
const [page, setPage] = useState(1)

Expand All @@ -34,8 +35,14 @@ export const useSession = () => {
loading: chatsLoading,
refetch: refetchChats,
} = useChatsService({
filter: [...selectedAgentNames, ...(searchText.length > 0 ? [searchText] : [])],
agentType: selectedAgentType,
filter: [
...(selectedAgentNames?.map((agent: any) => agent.value) || []),
...(searchText.length > 0 ? [searchText] : []),
...(selectedAgentType?.value === 'voice' || selectedAgentType?.value === 'text'
? [selectedAgentType?.value]
: []),
...(selectedCampaign?.map((campaign: any) => campaign.value) || []),
],
itemsCount: 20,
page,
})
Expand Down Expand Up @@ -105,7 +112,7 @@ export const useSession = () => {

const campaignOptions = campaigns?.map((campaign: any) => {
return {
value: campaign.name,
value: campaign.id,
label: `${campaign.name}`,
}
})
Expand All @@ -132,6 +139,9 @@ export const useSession = () => {
totalPages,
chatsLoading,
setSelectedAgentType,
selectedAgentType,
setSelectedCampaign,
selectedCampaign,
campaignOptions,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ export const useCampaignForm = () => {
const agentOptions = agentsData
?.filter(({ agent }) => agent.agent_type === 'voice')
?.map(({ agent }) => {
return { value: agent.id, label: agent.name }
return {
value: agent.id,
label: `${agent.name}${agent.role?.length > 0 ? ` - ${agent.role}` : ''}`,
}
})

const groupOptions = groupsData?.map(({ id, name }: { id: string; name: string }) => {
Expand Down
18 changes: 17 additions & 1 deletion apps/ui/src/plugins/contact/pages/Campaign/Campaigns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import { useMemo } from 'react'
import { t } from 'i18next'
import { useCampaigns } from './useCampaigns'
import { useNavigate } from 'react-router-dom'
import IconButton from 'share-ui/components/IconButton/IconButton'
import { StyledIconWrapper } from 'components/ChatCards/TeamChatCard'
import { StyledOpenIcon } from 'pages/Sessions/columnConfig'

const Campaigns = () => {
const navigate = useNavigate()
Expand Down Expand Up @@ -57,12 +60,25 @@ const Campaigns = () => {
{
Header: 'Actions',
accessor: 'id',
width: 50,
width: 80,
Cell: ({ cell }: any) => {
return (
<TableActionButtons
onDeleteClick={() => deleteCampaignHandler(cell.value)}
onEditClick={() => navigate(`/schedules/${cell.value}/edit-campaign`)}
customActions={
<IconButton
onClick={() => navigate(`/sessions?campaign=${cell.value}`)}
icon={() => (
<StyledIconWrapper>
<StyledOpenIcon />
</StyledIconWrapper>
)}
size={IconButton.sizes?.SMALL}
kind={IconButton.kinds?.TERTIARY}
ariaLabel='Go to Threads'
/>
}
/>
)
},
Expand Down
5 changes: 1 addition & 4 deletions apps/ui/src/services/chat/useChatsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,14 @@ function joinFilters(filters: string[]) {
export const useChatsService = ({
filter = [''],
page = 1,
agentType = null,
itemsCount = 10,
}: {
filter?: string[]
page?: number
itemsCount?: number
agentType?: 'voice' | 'text' | null
}) => {
const restPath = `/chat?${joinFilters(filter)}&page=${page}&per_page=${itemsCount}${
agentType ? `&agent_type=${agentType}` : ''
}`
const restPath = `/chat?${joinFilters(filter)}&page=${page}&per_page=${itemsCount}`
const { data, error, loading, refetch } = useQuery(CHATS_GQL, {
variables: { restPath },
fetchPolicy: 'cache-first',
Expand Down
Loading

0 comments on commit b1d20de

Please sign in to comment.