Skip to content

Commit

Permalink
Processes filtering logic (#835)
Browse files Browse the repository at this point in the history
* Add processes pagination filter by status

And updated the sidebar links to point to these new filters

* Remove unused method

* Minor varname change

* Review fixes
  • Loading branch information
elboletaire authored Nov 14, 2024
1 parent 0c2767d commit 8b50bb2
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 107 deletions.
8 changes: 4 additions & 4 deletions src/components/Dashboard/Menu/Options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { HiSquares2X2 } from 'react-icons/hi2'
import { IoIosSettings } from 'react-icons/io'
import { matchPath, useLocation } from 'react-router-dom'
import { generatePath, matchPath, useLocation } from 'react-router-dom'
import { Routes } from '~src/router/routes'
import { PricingModal } from '../PricingModal'
import { DashboardMenuItem } from './Item'
Expand Down Expand Up @@ -32,9 +32,9 @@ export const DashboardMenuOptions = () => {
label: t('voting_processes'),
icon: HiSquares2X2,
children: [
{ label: t('all'), route: Routes.dashboard.processes },
{ label: t('active'), route: '#active' },
{ label: t('finished'), route: '#finished' },
{ label: t('all'), route: generatePath(Routes.dashboard.processes, { page: 1 }) },
{ label: t('active'), route: generatePath(Routes.dashboard.processes, { status: 'ready', page: 1 }) },
{ label: t('finished'), route: generatePath(Routes.dashboard.processes, { status: 'results', page: 1 }) },
// { label: t('draft'), route: '#draft' },
],
},
Expand Down
19 changes: 8 additions & 11 deletions src/components/Organization/Dashboard/ProcessesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ import ProcessCard from './ProcessCard'
type Election = PublishedElection | InvalidElection

type ProcessesListProps = {
error: Error | null
loading: boolean
limit?: number
error?: Error | null
loading?: boolean
processes?: Election[]
}

const ProcessesList = ({ loading, processes, error, limit }: ProcessesListProps) => {
const ProcessesList = ({ loading, processes, error }: ProcessesListProps) => {
const { t } = useTranslation()

return (
Expand Down Expand Up @@ -47,13 +46,11 @@ const ProcessesList = ({ loading, processes, error, limit }: ProcessesListProps)
<VStack w='full'>
{processes &&
processes.length &&
processes?.map((election, key) =>
limit && key >= limit ? null : (
<ElectionProvider election={election} id={election.id} key={election.id}>
<ProcessCard />
</ElectionProvider>
)
)}
processes?.map((election) => (
<ElectionProvider election={election} id={election.id} key={election.id}>
<ProcessCard />
</ElectionProvider>
))}
{!loading && (!processes || !processes.length) && <NoElections />}
</VStack>
</VStack>
Expand Down
15 changes: 6 additions & 9 deletions src/components/Organization/Dashboard/Votings.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
import { Flex } from '@chakra-ui/react'
import { RoutedPagination } from '@vocdoni/chakra-components'
import { RoutedPaginationProvider, useOrganization, useRoutedPagination } from '@vocdoni/react-providers'
import { usePaginatedElections } from '~src/queries/organization'
import { RoutedPaginationProvider, useOrganization } from '@vocdoni/react-providers'
import { ElectionListWithPagination } from '@vocdoni/sdk'
import { Routes } from '~src/router/routes'
import ProcessesList from './ProcessesList'

const Votings = () => {
const Votings = ({ data }: { data: ElectionListWithPagination }) => {
const { organization } = useOrganization()

if (!organization) return null

return (
<RoutedPaginationProvider path={Routes.dashboard.processes}>
<VotingsList />
<VotingsList data={data} />
</RoutedPaginationProvider>
)
}

const VotingsList = () => {
const { page } = useRoutedPagination()
const { data, error, isLoading } = usePaginatedElections(page ?? 0)

const VotingsList = ({ data }: { data: ElectionListWithPagination }) => {
if (!data) return null

const { elections, pagination } = data

return (
<Flex flexDirection='column' flexGrow={1} gap={5} height='full'>
<ProcessesList processes={elections} error={error} loading={isLoading} />
<ProcessesList processes={elections} />
<Flex mt='auto' justifyContent='end'>
{!!elections?.length && <RoutedPagination pagination={pagination} />}
</Flex>
Expand Down
6 changes: 4 additions & 2 deletions src/elements/dashboard/processes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { ElectionListWithPagination } from '@vocdoni/sdk'
import { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { useOutletContext } from 'react-router-dom'
import { useLoaderData, useOutletContext } from 'react-router-dom'
import { DashboardContents } from '~components/Layout/Dashboard'
import Votings from '~components/Organization/Dashboard/Votings'
import { DashboardLayoutContext } from '~elements/LayoutDashboard'

const OrganizationVotings = () => {
const { t } = useTranslation()
const { setBack, setTitle } = useOutletContext<DashboardLayoutContext>()
const data = useLoaderData()

// Set page title
useEffect(() => {
Expand All @@ -17,7 +19,7 @@ const OrganizationVotings = () => {

return (
<DashboardContents>
<Votings />
<Votings data={data as ElectionListWithPagination} />
</DashboardContents>
)
}
Expand Down
39 changes: 18 additions & 21 deletions src/queries/organization.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import { useQuery } from '@tanstack/react-query'
import { useClient } from '@vocdoni/react-providers'
import { AccountData, FetchElectionsParameters, VocdoniSDKClient } from '@vocdoni/sdk'

export const useLatestElections = (limit = 5) => {
const { client, account } = useClient()

return useQuery({
enabled: !!account?.address,
queryKey: ['organization', 'elections', account?.address, 0],
queryFn: async () => client.fetchElections({ organizationId: account?.address, page: 0, limit }),
select: (data) => data.elections,
retry: false,
})
type PaginatedElectionsParams = {
page?: number
status?: FetchElectionsParameters['status']
}

export const usePaginatedElections = (page: number) => {
const { client, account } = useClient()

return useQuery({
enabled: !!account?.address,
queryKey: ['organization', 'elections', account?.address, page],
queryFn: async () => client.fetchElections({ organizationId: account?.address, page }),
})
}
export const paginatedElectionsQuery = (
account: AccountData,
client: VocdoniSDKClient,
params: PaginatedElectionsParams
) => ({
enabled: !!account?.address,
queryKey: ['organization', 'elections', account?.address, params],
queryFn: async () =>
client.fetchElections({
organizationId: account?.address,
page: params.page ? Number(params.page) - 1 : 0,
status: params.status?.toUpperCase() as FetchElectionsParameters['status'],
}),
})
124 changes: 64 additions & 60 deletions src/router/routes/dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useClient } from '@vocdoni/react-providers'
import { VocdoniSDKClient } from '@vocdoni/sdk'
import { lazy } from 'react'
// These aren't lazy loaded since they are main layouts and related components
import { useQueryClient } from '@tanstack/react-query'
import { Params } from 'react-router-dom'
import { Profile } from '~elements/dashboard/profile'
import Error from '~elements/Error'
import LayoutDashboard from '~elements/LayoutDashboard'
import { paginatedElectionsQuery } from '~src/queries/organization'
import { Routes } from '.'
import OrganizationProtectedRoute from '../OrganizationProtectedRoute'
import { SuspenseLoader } from '../SuspenseLoader'
Expand All @@ -19,76 +20,79 @@ const OrganizationTeam = lazy(() => import('~elements/dashboard/team'))
// others
const OrganizationDashboard = lazy(() => import('~components/Organization/Dashboard'))

const DashboardElements = (client: VocdoniSDKClient) => [
{
export const useDashboardRoutes = () => {
const queryClient = useQueryClient()
const { client, account } = useClient()

return {
element: (
<SuspenseLoader>
<LayoutDashboard />
<OrganizationProtectedRoute />
</SuspenseLoader>
),
children: [
{
path: Routes.dashboard.base,
element: (
<SuspenseLoader>
<OrganizationDashboard />
</SuspenseLoader>
),
},
{
path: Routes.dashboard.process,
element: (
<SuspenseLoader>
<DashboardProcessView />
</SuspenseLoader>
),
loader: async ({ params }: { params: Params<string> }) => client.fetchElection(params.id),
errorElement: <Error />,
},
{
path: Routes.dashboard.organization,
element: (
<SuspenseLoader>
<OrganizationEdit />
</SuspenseLoader>
),
},
{
path: Routes.dashboard.profile,
element: (
<SuspenseLoader>
<Profile />
</SuspenseLoader>
),
},
{
path: Routes.dashboard.processes,
element: (
<SuspenseLoader>
<DashboardProcesses />
</SuspenseLoader>
),
},
{
path: Routes.dashboard.team,
element: (
<SuspenseLoader>
<OrganizationTeam />
<LayoutDashboard />
</SuspenseLoader>
),
children: [
{
path: Routes.dashboard.base,
element: (
<SuspenseLoader>
<OrganizationDashboard />
</SuspenseLoader>
),
},
{
path: Routes.dashboard.process,
element: (
<SuspenseLoader>
<DashboardProcessView />
</SuspenseLoader>
),
loader: async ({ params }: { params: Params<string> }) => client.fetchElection(params.id),
errorElement: <Error />,
},
{
path: Routes.dashboard.organization,
element: (
<SuspenseLoader>
<OrganizationEdit />
</SuspenseLoader>
),
},
{
path: Routes.dashboard.profile,
element: (
<SuspenseLoader>
<Profile />
</SuspenseLoader>
),
},
{
path: Routes.dashboard.processes,
element: (
<SuspenseLoader>
<DashboardProcesses />
</SuspenseLoader>
),
loader: async ({ params }) =>
await queryClient.ensureQueryData(paginatedElectionsQuery(account, client, params)),
errorElement: <Error />,
},
{
path: Routes.dashboard.team,
element: (
<SuspenseLoader>
<OrganizationTeam />
</SuspenseLoader>
),
},
],
},
],
},
]

export const useDashboardRoutes = () => {
const { client } = useClient()
return {
element: (
<SuspenseLoader>
<OrganizationProtectedRoute />
</SuspenseLoader>
),
children: DashboardElements(client),
}
}

2 comments on commit 8b50bb2

@github-actions
Copy link

Choose a reason for hiding this comment

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

@github-actions
Copy link

Choose a reason for hiding this comment

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

Please sign in to comment.