Skip to content

Commit

Permalink
Merge pull request #661 from ItsMurumba/transaction-tests-minor-fixes
Browse files Browse the repository at this point in the history
Transaction Log Fixes
  • Loading branch information
drizzentic authored Sep 6, 2024
2 parents ef5e9cf + cbe2a7f commit 2d201a5
Show file tree
Hide file tree
Showing 13 changed files with 551 additions and 41 deletions.
6 changes: 5 additions & 1 deletion packages/root-config/src/microfrontend-layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
</route>
<route path="#!/transactions">
</route>
<route path="#!/transactions/:transactionId">
</route>
<route path="#!/audits">
</route>
<route path="#!/channels">
</route>
<route path="#!/audits">
Expand Down Expand Up @@ -50,7 +54,7 @@
<application name="@jembi/portal-admin"></application>
</div>
</route>
<route path="#!/transactions">
<route path="#!/transactions" exact>
<div style="flex-grow: 1">
<application name="@jembi/transaction-log"></application>
</div>
Expand Down
8 changes: 7 additions & 1 deletion packages/transaction-log/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const path = require('path')

module.exports = {
rootDir: 'src',
testEnvironment: 'jsdom',
Expand All @@ -6,7 +8,11 @@ module.exports = {
},
moduleNameMapper: {
'\\.(css)$': 'identity-obj-proxy',
'single-spa-react/parcel': 'single-spa-react/lib/cjs/parcel.cjs'
'single-spa-react/parcel': 'single-spa-react/lib/cjs/parcel.cjs',
'^@jembi/openhim-core-api$': path.resolve(
__dirname,
'../openhim-core-api/src/jembi-openhim-core-api.ts'
)
},
setupFilesAfterEnv: ['@testing-library/jest-dom']
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react'
import {Button} from '@mui/material'
import {StatusButtonProps} from '../../interfaces/index.interface'

const StatusButton: React.FC<StatusButtonProps> = ({status, buttonText}) => {
const buttonColor =
status === 'Processing'
? 'info'
: status === 'Pending Async'
? 'info'
: status === 'Successful'
? 'success'
: status === 'Completed'
? 'warning'
: status === 'Completed with error(s)'
? 'warning'
: 'error'

return (
<Button variant="contained" color={buttonColor}>
{buttonText}
</Button>
)
}

export default StatusButton
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const App: React.FC = () => {
const [client, setClient] = useState(NO_FILTER)
const [method, setMethod] = useState(NO_FILTER)
const [clients, setClients] = useState([])
const [loading, setLoading] = useState(false)
const [timestampFilter, setTimestampFilter] = useState<string | null>(null)

const fetchTransactionLogs = useCallback(
async (timestampFilter?: string) => {
Expand Down Expand Up @@ -112,17 +114,20 @@ const App: React.FC = () => {
fetchParams.filterPage = 0
}

const transactions = await getTransactions(fetchParams);
const newTransactions = await getTransactions(fetchParams)

const transactionsWithChannelDetails = await Promise.all(
transactions.map(async transaction => {
const newTransactionsWithChannelDetails = await Promise.all(
newTransactions.map(async transaction => {
const channelName = await fetchChannelDetails(transaction.channelID)
const clientName = await fetchClientDetails(transaction.clientID)
return {...transaction, channelName, clientName}
})
)

setTransactions(transactionsWithChannelDetails)
setTransactions(prevTransactions => [
...newTransactionsWithChannelDetails,
...prevTransactions
])
} catch (error) {
console.error('Error fetching logs:', error)
}
Expand All @@ -140,7 +145,8 @@ const App: React.FC = () => {
path,
param,
client,
method
method,
loading
]
)

Expand All @@ -165,6 +171,21 @@ const App: React.FC = () => {
fetchAvailableChannels(), fetchAvailableClients()
}, [fetchTransactionLogs, fetchAvailableChannels, fetchAvailableClients])

useEffect(() => {
const interval = setInterval(() => {
const currentTimestamp = new Date().toISOString()
setTimestampFilter(currentTimestamp)
}, 5000)

return () => clearInterval(interval)
}, [])

useEffect(() => {
if (timestampFilter) {
fetchTransactionLogs(timestampFilter)
}
}, [timestampFilter, fetchTransactionLogs])

const handleTabChange = (event: React.ChangeEvent<{}>, newValue: number) => {
setTabValue(newValue)
}
Expand All @@ -191,8 +212,16 @@ const App: React.FC = () => {
}
}

const loadMore = () => {
setLimit(prevLimit => prevLimit + 20)
const loadMore = async () => {
setLoading(true)
try {
setLimit(prevLimit => prevLimit + 20)

await fetchTransactionLogs()
} catch (error) {
} finally {
setLoading(false)
}
}

const filteredTransactions = transactions.filter(transaction => {
Expand All @@ -208,8 +237,8 @@ const App: React.FC = () => {
].some(field => field?.toLowerCase().includes(searchTerm))
})

const handleRowClick = (transaction) => {
console.log('Transaction clicked:', transaction);
const handleRowClick = transaction => {
console.log('Transaction clicked:', transaction)
}

return (
Expand Down Expand Up @@ -311,6 +340,7 @@ const App: React.FC = () => {
<TransactionLogTable
transactions={filteredTransactions}
loadMore={loadMore}
loading={loading}
onRowClick={handleRowClick}
/>
</CardContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,68 @@ import {
Typography,
Button,
IconButton,
TableFooter
TableFooter,
CircularProgress
} from '@mui/material'
import SettingsIcon from '@mui/icons-material/Settings'
import SettingsDialog from '../dialogs/settings.dialog.component'
import {ChevronRight} from '@mui/icons-material'
import LockIcon from '@mui/icons-material/Lock'
import convertTimestampFormat from '../helpers/timestampformat.helper.component'
import StatusButton from '../buttons/status.button.component'

const TransactionLogTable: React.FC<{
transactions: any[]
loadMore: () => void
onRowClick: (transaction) => void
}> = ({transactions, loadMore, onRowClick}) => {
loading: boolean
onRowClick: (transaction: any) => void
}> = ({transactions, loadMore, onRowClick, loading}) => {
const [settingsOpen, setSettingsOpen] = useState(false)
const [openInNewTab, setOpenInNewTab] = useState(false)
const [autoUpdate, setAutoUpdate] = useState(false)
const [selectedRows, setSelectedRows] = useState<Set<number>>(new Set())
const [selectAll, setSelectAll] = useState(false)

const handleSettingsApply = () => {
setSettingsOpen(false)
}

const handleRowClick = (event: React.MouseEvent, transaction: {_id: any}) => {
const nonClickableColumnClass = 'non-clickable-column'
if ((event.target as HTMLElement).closest(`.${nonClickableColumnClass}`)) {
return
}
const transactionDetailsUrl = `/#!/transactions/${transaction._id}`

if (openInNewTab) {
window.open(transactionDetailsUrl, '_blank')
} else {
window.location.href = transactionDetailsUrl
}
}

const handleRowSelect = (rowIndex: number) => {
setSelectedRows(prevSelectedRows => {
const newSelectedRows = new Set(prevSelectedRows)
if (newSelectedRows.has(rowIndex)) {
newSelectedRows.delete(rowIndex)
} else {
newSelectedRows.add(rowIndex)
}
return newSelectedRows
})
}

const handleSelectAll = () => {
if (selectAll) {
setSelectedRows(new Set())
} else {
const allRowIndexes = transactions.map((_, index) => index)
setSelectedRows(new Set(allRowIndexes))
}
setSelectAll(!selectAll)
}

return (
<Box sx={{padding: '16px'}}>
<Box
Expand All @@ -55,7 +98,7 @@ const TransactionLogTable: React.FC<{
<TableHead>
<TableRow>
<TableCell padding="checkbox">
<Checkbox />
<Checkbox checked={selectAll} onChange={handleSelectAll} />
</TableCell>
<TableCell>Type</TableCell>
<TableCell>Method</TableCell>
Expand All @@ -65,29 +108,38 @@ const TransactionLogTable: React.FC<{
<TableCell>Params</TableCell>
<TableCell>Channel</TableCell>
<TableCell>Client</TableCell>
<TableCell>Status</TableCell>
<TableCell>Time</TableCell>
</TableRow>
</TableHead>
<TableBody>
{transactions.map((transaction, index) => (
<TableRow key={index} hover style={{cursor: 'pointer'}} onClick={() => onRowClick(transaction)}>
<TableCell padding="checkbox">
<Checkbox />
<TableRow
key={index}
hover
style={{cursor: 'pointer'}}
onClick={event => handleRowClick(event, transaction)}
>
<TableCell
padding="checkbox"
className="non-clickable-column"
>
<Checkbox
checked={selectedRows.has(index)}
onChange={() => handleRowSelect(index)}
/>
</TableCell>
<TableCell>
<svg
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
<IconButton
sx={{
height: '32px',
width: '32px',
backgroundColor: '#FECDD2',
borderRadius: 0
}}
>
<rect width="32" height="32" rx="4" fill="#FECDD2" />
<path
d="M22 12H21V10C21 7.24 18.76 5 16 5C13.24 5 11 7.24 11 10V12H10C8.9 12 8 12.9 8 14V24C8 25.1 8.9 26 10 26H22C23.1 26 24 25.1 24 24V14C24 12.9 23.1 12 22 12ZM16 21C14.9 21 14 20.1 14 19C14 17.9 14.9 17 16 17C17.1 17 18 17.9 18 19C18 20.1 17.1 21 16 21ZM19.1 12H12.9V10C12.9 8.29 14.29 6.9 16 6.9C17.71 6.9 19.1 8.29 19.1 10V12Z"
fill="#C62828"
/>
</svg>
<LockIcon style={{color: '#C62828'}} />
</IconButton>
</TableCell>
<TableCell>{transaction.request.method}</TableCell>
<TableCell>{transaction.request.host}</TableCell>
Expand All @@ -96,15 +148,31 @@ const TransactionLogTable: React.FC<{
<TableCell>{transaction.request.params}</TableCell>
<TableCell>{transaction.channelName}</TableCell>
<TableCell>{transaction.clientName}</TableCell>
<TableCell>{transaction.request.timestamp}</TableCell>
<TableCell>
<StatusButton
status={transaction.status}
buttonText={transaction.status}
/>
</TableCell>
<TableCell>
{convertTimestampFormat(transaction.request.timestamp)}
</TableCell>
</TableRow>
))}
</TableBody>
<TableFooter>
<TableRow>
<TableCell colSpan={10} align="right">
<Button onClick={loadMore} endIcon={<ChevronRight />}>
Load 20 more results
<TableCell colSpan={11} align="right">
<Button
onClick={loadMore}
endIcon={<ChevronRight />}
disabled={loading}
>
{loading ? (
<CircularProgress size={24} />
) : (
'Load 20 more results'
)}
</Button>
</TableCell>
</TableRow>
Expand Down
Loading

0 comments on commit 2d201a5

Please sign in to comment.