Skip to content

Commit ab76c48

Browse files
authored
Add table view to tools page (#2870)
1 parent 877bc20 commit ab76c48

File tree

2 files changed

+206
-14
lines changed

2 files changed

+206
-14
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import PropTypes from 'prop-types'
2+
import { useSelector } from 'react-redux'
3+
import { styled } from '@mui/material/styles'
4+
import { tableCellClasses } from '@mui/material/TableCell'
5+
import {
6+
Button,
7+
Paper,
8+
Skeleton,
9+
Table,
10+
TableBody,
11+
TableCell,
12+
TableContainer,
13+
TableHead,
14+
TableRow,
15+
Typography,
16+
useTheme
17+
} from '@mui/material'
18+
19+
const StyledTableCell = styled(TableCell)(({ theme }) => ({
20+
borderColor: theme.palette.grey[900] + 25,
21+
22+
[`&.${tableCellClasses.head}`]: {
23+
color: theme.palette.grey[900]
24+
},
25+
[`&.${tableCellClasses.body}`]: {
26+
fontSize: 14,
27+
height: 64
28+
}
29+
}))
30+
31+
const StyledTableRow = styled(TableRow)(() => ({
32+
// hide last border
33+
'&:last-child td, &:last-child th': {
34+
border: 0
35+
}
36+
}))
37+
38+
export const ToolsTable = ({ data, isLoading, onSelect }) => {
39+
const theme = useTheme()
40+
const customization = useSelector((state) => state.customization)
41+
42+
return (
43+
<>
44+
<TableContainer sx={{ border: 1, borderColor: theme.palette.grey[900] + 25, borderRadius: 2 }} component={Paper}>
45+
<Table sx={{ minWidth: 650 }} size='small' aria-label='a dense table'>
46+
<TableHead
47+
sx={{
48+
backgroundColor: customization.isDarkMode ? theme.palette.common.black : theme.palette.grey[100],
49+
height: 56
50+
}}
51+
>
52+
<TableRow>
53+
<StyledTableCell component='th' scope='row' key='0'>
54+
Name
55+
</StyledTableCell>
56+
<StyledTableCell key='1'>Description</StyledTableCell>
57+
<StyledTableCell component='th' scope='row' key='3'>
58+
&nbsp;
59+
</StyledTableCell>
60+
</TableRow>
61+
</TableHead>
62+
<TableBody>
63+
{isLoading ? (
64+
<>
65+
<StyledTableRow>
66+
<StyledTableCell>
67+
<Skeleton variant='text' />
68+
</StyledTableCell>
69+
<StyledTableCell>
70+
<Skeleton variant='text' />
71+
</StyledTableCell>
72+
<StyledTableCell>
73+
<Skeleton variant='text' />
74+
</StyledTableCell>
75+
</StyledTableRow>
76+
<StyledTableRow>
77+
<StyledTableCell>
78+
<Skeleton variant='text' />
79+
</StyledTableCell>
80+
<StyledTableCell>
81+
<Skeleton variant='text' />
82+
</StyledTableCell>
83+
<StyledTableCell>
84+
<Skeleton variant='text' />
85+
</StyledTableCell>
86+
</StyledTableRow>
87+
</>
88+
) : (
89+
<>
90+
{data?.map((row, index) => (
91+
<StyledTableRow key={index}>
92+
<StyledTableCell sx={{ display: 'flex', alignItems: 'center', gap: 1 }} key='0'>
93+
<div
94+
style={{
95+
width: 35,
96+
height: 35,
97+
display: 'flex',
98+
flexShrink: 0,
99+
marginRight: 10,
100+
borderRadius: '50%',
101+
backgroundImage: `url(${row.iconSrc})`,
102+
backgroundSize: 'contain',
103+
backgroundRepeat: 'no-repeat',
104+
backgroundPosition: 'center center'
105+
}}
106+
></div>
107+
<Typography
108+
sx={{
109+
display: '-webkit-box',
110+
fontSize: 14,
111+
fontWeight: 500,
112+
WebkitLineClamp: 2,
113+
WebkitBoxOrient: 'vertical',
114+
textOverflow: 'ellipsis',
115+
overflow: 'hidden'
116+
}}
117+
>
118+
<Button onClick={() => onSelect(row)} sx={{ textAlign: 'left' }}>
119+
{row.templateName || row.name}
120+
</Button>
121+
</Typography>
122+
</StyledTableCell>
123+
<StyledTableCell key='1'>
124+
<Typography sx={{ overflowWrap: 'break-word', whiteSpace: 'pre-line' }}>
125+
{row.description || ''}
126+
</Typography>
127+
</StyledTableCell>
128+
<StyledTableCell key='3'></StyledTableCell>
129+
</StyledTableRow>
130+
))}
131+
</>
132+
)}
133+
</TableBody>
134+
</Table>
135+
</TableContainer>
136+
</>
137+
)
138+
}
139+
140+
ToolsTable.propTypes = {
141+
data: PropTypes.array,
142+
isLoading: PropTypes.bool,
143+
onSelect: PropTypes.func
144+
}

packages/ui/src/views/tools/index.jsx

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffect, useState, useRef } from 'react'
22

33
// material-ui
4-
import { Box, Stack, Button, ButtonGroup, Skeleton } from '@mui/material'
4+
import { Box, Stack, Button, ButtonGroup, Skeleton, ToggleButtonGroup, ToggleButton } from '@mui/material'
55

66
// project imports
77
import MainCard from '@/ui-component/cards/MainCard'
@@ -10,6 +10,7 @@ import { gridSpacing } from '@/store/constant'
1010
import ToolEmptySVG from '@/assets/images/tools_empty.svg'
1111
import { StyledButton } from '@/ui-component/button/StyledButton'
1212
import ToolDialog from './ToolDialog'
13+
import { ToolsTable } from '@/ui-component/table/ToolsListTable'
1314

1415
// API
1516
import toolsApi from '@/api/tools'
@@ -18,22 +19,31 @@ import toolsApi from '@/api/tools'
1819
import useApi from '@/hooks/useApi'
1920

2021
// icons
21-
import { IconPlus, IconFileUpload } from '@tabler/icons-react'
22+
import { IconPlus, IconFileUpload, IconLayoutGrid, IconList } from '@tabler/icons-react'
2223
import ViewHeader from '@/layout/MainLayout/ViewHeader'
2324
import ErrorBoundary from '@/ErrorBoundary'
25+
import { useTheme } from '@mui/material/styles'
2426

2527
// ==============================|| CHATFLOWS ||============================== //
2628

2729
const Tools = () => {
30+
const theme = useTheme()
2831
const getAllToolsApi = useApi(toolsApi.getAllTools)
2932

3033
const [isLoading, setLoading] = useState(true)
3134
const [error, setError] = useState(null)
3235
const [showDialog, setShowDialog] = useState(false)
3336
const [dialogProps, setDialogProps] = useState({})
37+
const [view, setView] = useState(localStorage.getItem('toolsDisplayStyle') || 'card')
3438

3539
const inputRef = useRef(null)
3640

41+
const handleChange = (event, nextView) => {
42+
if (nextView === null) return
43+
localStorage.setItem('toolsDisplayStyle', nextView)
44+
setView(nextView)
45+
}
46+
3747
const onUploadFile = (file) => {
3848
try {
3949
const dialogProp = {
@@ -118,6 +128,38 @@ const Tools = () => {
118128
) : (
119129
<Stack flexDirection='column' sx={{ gap: 3 }}>
120130
<ViewHeader title='Tools'>
131+
<ToggleButtonGroup
132+
sx={{ borderRadius: 2, maxHeight: 40 }}
133+
value={view}
134+
color='primary'
135+
exclusive
136+
onChange={handleChange}
137+
>
138+
<ToggleButton
139+
sx={{
140+
borderColor: theme.palette.grey[900] + 25,
141+
borderRadius: 2,
142+
color: theme?.customization?.isDarkMode ? 'white' : 'inherit'
143+
}}
144+
variant='contained'
145+
value='card'
146+
title='Card View'
147+
>
148+
<IconLayoutGrid />
149+
</ToggleButton>
150+
<ToggleButton
151+
sx={{
152+
borderColor: theme.palette.grey[900] + 25,
153+
borderRadius: 2,
154+
color: theme?.customization?.isDarkMode ? 'white' : 'inherit'
155+
}}
156+
variant='contained'
157+
value='list'
158+
title='List View'
159+
>
160+
<IconList />
161+
</ToggleButton>
162+
</ToggleButtonGroup>
121163
<Box sx={{ display: 'flex', alignItems: 'center' }}>
122164
<Button
123165
variant='outlined'
@@ -147,19 +189,25 @@ const Tools = () => {
147189
</StyledButton>
148190
</ButtonGroup>
149191
</ViewHeader>
150-
{isLoading ? (
151-
<Box display='grid' gridTemplateColumns='repeat(3, 1fr)' gap={gridSpacing}>
152-
<Skeleton variant='rounded' height={160} />
153-
<Skeleton variant='rounded' height={160} />
154-
<Skeleton variant='rounded' height={160} />
155-
</Box>
192+
{!view || view === 'card' ? (
193+
<>
194+
{isLoading ? (
195+
<Box display='grid' gridTemplateColumns='repeat(3, 1fr)' gap={gridSpacing}>
196+
<Skeleton variant='rounded' height={160} />
197+
<Skeleton variant='rounded' height={160} />
198+
<Skeleton variant='rounded' height={160} />
199+
</Box>
200+
) : (
201+
<Box display='grid' gridTemplateColumns='repeat(3, 1fr)' gap={gridSpacing}>
202+
{getAllToolsApi.data &&
203+
getAllToolsApi.data.map((data, index) => (
204+
<ItemCard data={data} key={index} onClick={() => edit(data)} />
205+
))}
206+
</Box>
207+
)}
208+
</>
156209
) : (
157-
<Box display='grid' gridTemplateColumns='repeat(3, 1fr)' gap={gridSpacing}>
158-
{getAllToolsApi.data &&
159-
getAllToolsApi.data.map((data, index) => (
160-
<ItemCard data={data} key={index} onClick={() => edit(data)} />
161-
))}
162-
</Box>
210+
<ToolsTable data={getAllToolsApi.data} isLoading={isLoading} onSelect={edit} />
163211
)}
164212
{!isLoading && (!getAllToolsApi.data || getAllToolsApi.data.length === 0) && (
165213
<Stack sx={{ alignItems: 'center', justifyContent: 'center' }} flexDirection='column'>

0 commit comments

Comments
 (0)