Skip to content

Commit 9d43852

Browse files
authored
Marketplace page UI/ UX enhancements (#4819)
* style enhancements * Introduce autocomplete to select usecases * add grid gap property * add tooltip to display remaining selected items on hover * use ordered list to show more items
1 parent ee5ab1b commit 9d43852

File tree

2 files changed

+90
-56
lines changed
  • packages/ui/src

2 files changed

+90
-56
lines changed

packages/ui/src/layout/MainLayout/Header/ProfileSection/index.jsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,14 @@ const ExportDialog = ({ show, onCancel, onExport }) => {
101101
</DialogTitle>
102102
<DialogContent>
103103
{!isExporting && (
104-
<Stack direction='row' sx={{ gap: 1, flexWrap: 'wrap' }}>
104+
<Stack
105+
direction='row'
106+
sx={{
107+
display: 'grid',
108+
gridTemplateColumns: 'repeat(2, 1fr)',
109+
gap: 1
110+
}}
111+
>
105112
{dataToExport.map((data, index) => (
106113
<FormControlLabel
107114
key={index}

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

Lines changed: 82 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ import {
2020
ToggleButtonGroup,
2121
MenuItem,
2222
Button,
23-
Tabs
23+
Tabs,
24+
Autocomplete,
25+
TextField,
26+
Chip,
27+
Tooltip
2428
} from '@mui/material'
2529
import { useTheme } from '@mui/material/styles'
2630
import { IconLayoutGrid, IconList, IconX } from '@tabler/icons-react'
@@ -621,63 +625,86 @@ const Marketplace = () => {
621625
</ToggleButtonGroup>
622626
</ViewHeader>
623627
{hasPermission('templates:marketplace') && hasPermission('templates:custom') && (
624-
<Tabs value={activeTabValue} onChange={handleTabChange} textColor='primary' aria-label='tabs' centered>
625-
<PermissionTab permissionId='templates:marketplace' value={0} label='Community Templates' />
626-
<PermissionTab permissionId='templates:custom' value={1} label='My Templates' />
627-
</Tabs>
628+
<Stack direction='row' justifyContent='space-between' sx={{ mb: 2 }}>
629+
<Tabs value={activeTabValue} onChange={handleTabChange} textColor='primary' aria-label='tabs'>
630+
<PermissionTab permissionId='templates:marketplace' value={0} label='Community Templates' />
631+
<PermissionTab permissionId='templates:custom' value={1} label='My Templates' />
632+
</Tabs>
633+
<Autocomplete
634+
id='useCases'
635+
multiple
636+
size='small'
637+
options={usecases}
638+
value={selectedUsecases}
639+
onChange={(_, newValue) => setSelectedUsecases(newValue)}
640+
disableCloseOnSelect
641+
getOptionLabel={(option) => option}
642+
isOptionEqualToValue={(option, value) => option === value}
643+
renderOption={(props, option, { selected }) => {
644+
const isDisabled = eligibleUsecases.length > 0 && !eligibleUsecases.includes(option)
645+
646+
return (
647+
<li {...props} style={{ pointerEvents: isDisabled ? 'none' : 'auto' }}>
648+
<Checkbox checked={selected} color='success' disabled={isDisabled} />
649+
<ListItemText primary={option} />
650+
</li>
651+
)
652+
}}
653+
renderInput={(params) => <TextField {...params} label='Usecases' />}
654+
sx={{
655+
width: 300
656+
}}
657+
limitTags={2}
658+
renderTags={(value, getTagProps) => {
659+
const totalTags = value.length
660+
const limitTags = 2
661+
662+
return (
663+
<>
664+
{value.slice(0, limitTags).map((option, index) => (
665+
<Chip
666+
{...getTagProps({ index })}
667+
key={index}
668+
label={option}
669+
sx={{
670+
height: 24,
671+
'& .MuiSvgIcon-root': {
672+
fontSize: 16,
673+
background: 'None'
674+
}
675+
}}
676+
/>
677+
))}
678+
679+
{totalTags > limitTags && (
680+
<Tooltip
681+
title={
682+
<ol style={{ paddingLeft: '20px' }}>
683+
{value.slice(limitTags).map((item, i) => (
684+
<li key={i}>{item}</li>
685+
))}
686+
</ol>
687+
}
688+
placement='top'
689+
>
690+
+{totalTags - limitTags}
691+
</Tooltip>
692+
)}
693+
</>
694+
)
695+
}}
696+
slotProps={{
697+
paper: {
698+
sx: {
699+
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.2)'
700+
}
701+
}
702+
}}
703+
/>
704+
</Stack>
628705
)}
629706
<Available permission='templates:marketplace'>
630707
<TabPanel value={activeTabValue} index={0}>
631-
<Stack direction='row' sx={{ gap: 2, my: 2, alignItems: 'center', flexWrap: 'wrap' }}>
632-
{usecases.map((usecase, index) => (
633-
<FormControlLabel
634-
key={index}
635-
size='small'
636-
control={
637-
<Checkbox
638-
disabled={eligibleUsecases.length === 0 ? true : !eligibleUsecases.includes(usecase)}
639-
color='success'
640-
checked={selectedUsecases.includes(usecase)}
641-
onChange={(event) => {
642-
setSelectedUsecases(
643-
event.target.checked
644-
? [...selectedUsecases, usecase]
645-
: selectedUsecases.filter((item) => item !== usecase)
646-
)
647-
}}
648-
sx={{
649-
'& .MuiSvgIcon-root': {
650-
color:
651-
eligibleUsecases.length === 0 || !eligibleUsecases.includes(usecase)
652-
? '#888 !important'
653-
: undefined
654-
}
655-
}}
656-
/>
657-
}
658-
label={usecase}
659-
sx={{
660-
'& .MuiFormControlLabel-label': {
661-
color:
662-
eligibleUsecases.length === 0 || !eligibleUsecases.includes(usecase)
663-
? '#888 !important'
664-
: undefined
665-
}
666-
}}
667-
/>
668-
))}
669-
</Stack>
670-
{selectedUsecases.length > 0 && (
671-
<Button
672-
sx={{ width: 'max-content', mb: 2, borderRadius: '20px' }}
673-
variant='outlined'
674-
onClick={() => clearAllUsecases()}
675-
startIcon={<IconX />}
676-
>
677-
Clear All
678-
</Button>
679-
)}
680-
681708
{!view || view === 'card' ? (
682709
<>
683710
{isLoading ? (

0 commit comments

Comments
 (0)