Skip to content

Commit

Permalink
Merge pull request #154 from TurtIeSocks/new-filtering
Browse files Browse the repository at this point in the history
Better Filtering for Admin Panel
  • Loading branch information
TurtIeSocks authored Apr 24, 2023
2 parents 01c8c84 + 3a95683 commit 3ed922a
Show file tree
Hide file tree
Showing 14 changed files with 417 additions and 140 deletions.
43 changes: 43 additions & 0 deletions client/src/pages/admin/actions/Extras.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as React from 'react'
import { DeleteWithUndoButton } from 'react-admin'
import { IconButton, Menu, MenuItem } from '@mui/material'
import MoreVertIcon from '@mui/icons-material/MoreVert'

import { ExportButton } from './Export'
import { PushToProd } from './PushToApi'

export function ExtraMenuActions({ resource }: { resource: string }) {
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null)

const handleClose = (e: React.MouseEvent) => {
e.stopPropagation()
setAnchorEl(null)
}

return (
<>
<IconButton
onClick={(e) => {
e.stopPropagation()
setAnchorEl(e.currentTarget)
}}
>
<MoreVertIcon />
</IconButton>
<Menu open={!!anchorEl} anchorEl={anchorEl} onClose={handleClose}>
<MenuItem onClick={handleClose}>
<DeleteWithUndoButton />
</MenuItem>
<MenuItem onClick={handleClose}>
<ExportButton resource={resource} />
</MenuItem>
<MenuItem
onClick={handleClose}
sx={{ display: { xs: 'flex', sm: 'none' } }}
>
<PushToProd resource={resource} />
</MenuItem>
</Menu>
</>
)
}
12 changes: 10 additions & 2 deletions client/src/pages/admin/actions/PushToApi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,29 @@ import {
import { useMutation } from 'react-query'

import type { BasicKojiEntry } from '@assets/types'
import { capitalize } from '@mui/material'
import { SxProps, capitalize } from '@mui/material'
import { fetchWrapper } from '@services/fetches'

export function BaseButton({
onClick,
sx,
}: {
onClick: React.MouseEventHandler<HTMLButtonElement> | undefined
sx?: SxProps
}) {
return (
<Button label="Sync" size="small" onClick={onClick}>
<Button label="Sync" size="small" onClick={onClick} sx={sx}>
<SyncIcon />
</Button>
)
}

export function PushToProd<T extends BasicKojiEntry>({
resource,
sx,
}: {
resource: string
sx?: SxProps
}) {
const record = useRecordContext<T>()
const notify = useNotify()
Expand All @@ -52,6 +56,7 @@ export function PushToProd<T extends BasicKojiEntry>({

return (
<BaseButton
sx={sx}
onClick={(event) => {
event.stopPropagation()
sync.mutate()
Expand All @@ -62,8 +67,10 @@ export function PushToProd<T extends BasicKojiEntry>({

export function BulkPushToProd<T extends BasicKojiEntry>({
resource,
sx,
}: {
resource: string
sx?: SxProps
}) {
const { selectedIds } = useListContext<T>()
const unselectAll = useUnselectAll(resource)
Expand Down Expand Up @@ -95,6 +102,7 @@ export function BulkPushToProd<T extends BasicKojiEntry>({

return (
<BaseButton
sx={sx}
onClick={(event) => {
event.stopPropagation()
unselectAll()
Expand Down
69 changes: 69 additions & 0 deletions client/src/pages/admin/geofence/GeofenceFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/* eslint-disable import/no-extraneous-dependencies */
import * as React from 'react'
import {
// SavedQueriesList,
FilterLiveSearch,
FilterList,
FilterListItem,
useGetList,
} from 'react-admin'
import { useQuery } from 'react-query'
import { Card, CardContent } from '@mui/material'
import AutoModeIcon from '@mui/icons-material/AutoMode'
import AccountTree from '@mui/icons-material/AccountTree'
import MapIcon from '@mui/icons-material/Map'
import SupervisedUserCircleIcon from '@mui/icons-material/SupervisedUserCircle'

import { useStatic } from '@hooks/useStatic'
import { RDM_FENCES, UNOWN_FENCES } from '@assets/constants'
import { KojiGeofence, KojiProject, KojiResponse } from '@assets/types'
import { fetchWrapper } from '@services/fetches'

export function GeofenceFilter() {
const { scannerType } = useStatic.getState()
const projectData = useGetList<KojiProject>('project')
const { data } = useQuery('parents', () =>
fetchWrapper<KojiResponse<KojiGeofence[]>>(
'/internal/admin/geofence/parent',
),
)
return (
<Card sx={{ order: -1, width: 200 }}>
<CardContent>
{/* <SavedQueriesList /> */}
<FilterLiveSearch />
<FilterList label="Project" icon={<AccountTree />}>
{(projectData?.data || []).map((project) => (
<FilterListItem
key={project.id}
label={project.name}
value={{ project: project.id }}
/>
))}
</FilterList>
<FilterList label="Parent" icon={<SupervisedUserCircleIcon />}>
{(data?.data || []).map((parent) => (
<FilterListItem
key={parent.id}
label={parent.name}
value={{ parent: parent.id }}
/>
))}
</FilterList>
<FilterList label="Geography Type" icon={<MapIcon />}>
{['Polygon', 'MultiPolygon'].map((geotype) => (
<FilterListItem key={geotype} label={geotype} value={{ geotype }} />
))}
</FilterList>
<FilterList label="Mode" icon={<AutoModeIcon />}>
{[
...(scannerType === 'rdm' ? RDM_FENCES : UNOWN_FENCES),
'unset',
].map((mode) => (
<FilterListItem key={mode} label={mode} value={{ mode }} />
))}
</FilterList>
</CardContent>
</Card>
)
}
12 changes: 5 additions & 7 deletions client/src/pages/admin/geofence/GeofenceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,23 @@ import * as React from 'react'
import {
BulkDeleteWithUndoButton,
Datagrid,
DeleteWithUndoButton,
EditButton,
List,
Pagination,
TextField,
TopToolbar,
CreateButton,
SearchInput,
ReferenceField,
} from 'react-admin'

import { ExportPolygon } from '@components/dialogs/Polygon'

import { GeofenceFilter } from './GeofenceFilter'
import { BulkAssignButton } from '../actions/AssignProjectFence'
import { BulkExportButton, ExportButton } from '../actions/Export'
import { BulkExportButton } from '../actions/Export'
import { BulkPushToProd, PushToProd } from '../actions/PushToApi'
import { GeofenceExpand } from './GeofenceExpand'
import { BulkAssignFenceButton } from '../actions/AssignParentFence'
import { ExtraMenuActions } from '../actions/Extras'

function ListActions() {
return (
Expand All @@ -45,7 +44,7 @@ export default function GeofenceList() {
return (
<>
<List
filters={[<SearchInput source="q" alwaysOn />]}
aside={<GeofenceFilter />}
pagination={<Pagination rowsPerPageOptions={[25, 50, 100]} />}
title="Geofences"
perPage={25}
Expand All @@ -62,9 +61,8 @@ export default function GeofenceList() {
<TextField source="mode" />
<TextField source="geo_type" />
<EditButton />
<DeleteWithUndoButton />
<PushToProd resource="geofence" />
<ExportButton resource="geofence" />
<ExtraMenuActions resource="geofence" />
</Datagrid>
</List>
<ExportPolygon />
Expand Down
53 changes: 53 additions & 0 deletions client/src/pages/admin/route/RouteFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* eslint-disable import/no-extraneous-dependencies */
import * as React from 'react'
import {
// SavedQueriesList,
FilterLiveSearch,
FilterList,
FilterListItem,
} from 'react-admin'
import { useQuery } from 'react-query'
import { Card, CardContent } from '@mui/material'
import AutoModeIcon from '@mui/icons-material/AutoMode'
import SupervisedUserCircleIcon from '@mui/icons-material/SupervisedUserCircle'

import { useStatic } from '@hooks/useStatic'
import { RDM_ROUTES, UNOWN_ROUTES } from '@assets/constants'
import { BasicKojiEntry, KojiResponse } from '@assets/types'
import { fetchWrapper } from '@services/fetches'

export function RouteFilter() {
const { scannerType } = useStatic.getState()
const { data } = useQuery('unique_geofences', () =>
fetchWrapper<KojiResponse<BasicKojiEntry[]>>(
'/internal/admin/route/parent',
),
)
return (
<Card sx={{ order: -1, width: 225 }}>
<CardContent>
{/* <SavedQueriesList /> */}
<FilterLiveSearch />
<FilterList label="Mode" icon={<AutoModeIcon />}>
{[
...(scannerType === 'rdm' ? RDM_ROUTES : UNOWN_ROUTES),
'unset',
].map((mode) => (
<FilterListItem key={mode} label={mode} value={{ mode }} />
))}
</FilterList>
<FilterList label="Geofence" icon={<SupervisedUserCircleIcon />}>
<div style={{ maxHeight: 400, overflow: 'auto' }}>
{(data?.data || []).map((fence) => (
<FilterListItem
key={fence.id}
label={fence.name}
value={{ geofenceid: fence.id }}
/>
))}
</div>
</FilterList>
</CardContent>
</Card>
)
}
18 changes: 10 additions & 8 deletions client/src/pages/admin/route/RouteList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import * as React from 'react'
import {
BulkDeleteWithUndoButton,
Datagrid,
DeleteWithUndoButton,
EditButton,
List,
NumberField,
Expand All @@ -11,12 +10,13 @@ import {
TopToolbar,
CreateButton,
ReferenceField,
SearchInput,
} from 'react-admin'
import { ExportPolygon } from '@components/dialogs/Polygon'

import { BulkExportButton, ExportButton } from '../actions/Export'
import { BulkExportButton } from '../actions/Export'
import { BulkPushToProd, PushToProd } from '../actions/PushToApi'
import { RouteFilter } from './RouteFilter'
import { ExtraMenuActions } from '../actions/Extras'

function ListActions() {
return (
Expand All @@ -29,8 +29,8 @@ function ListActions() {
function BulkActions() {
return (
<>
<BulkDeleteWithUndoButton resource="route" />
<BulkPushToProd resource="route" />
<BulkDeleteWithUndoButton resource="route" size="small" />
<BulkExportButton resource="route" />
</>
)
Expand All @@ -40,7 +40,7 @@ export default function RouteList() {
return (
<>
<List
filters={[<SearchInput source="q" alwaysOn />]}
aside={<RouteFilter />}
pagination={<Pagination rowsPerPageOptions={[25, 50, 100]} />}
title="Routes"
perPage={25}
Expand All @@ -54,9 +54,11 @@ export default function RouteList() {
<ReferenceField source="geofence_id" reference="geofence" />
<NumberField source="hops" label="Hops" sortable={false} />
<EditButton />
<DeleteWithUndoButton />
<PushToProd resource="route" />
<ExportButton resource="route" />
<PushToProd
resource="route"
sx={{ display: { xs: 'none', sm: 'flex' } }}
/>
<ExtraMenuActions resource="route" />
</Datagrid>
</List>
<ExportPolygon />
Expand Down
1 change: 1 addition & 0 deletions server/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ pub async fn start() -> io::Result<()> {
.service(
web::scope("/admin")
.service(private::admin::paginate)
.service(private::admin::parent_list)
.service(private::admin::get_all)
.service(private::admin::search)
.service(private::admin::assign)
Expand Down
Loading

1 comment on commit 3ed922a

@vercel
Copy link

@vercel vercel bot commented on 3ed922a Apr 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

koji – ./

koji-git-main-turtiesocks.vercel.app
koji-turtiesocks.vercel.app
koji.vercel.app

Please sign in to comment.