Skip to content

Commit

Permalink
Merge pull request #9 from SergeiPatiakin/SergeiPatiakin/react-query
Browse files Browse the repository at this point in the history
Use react-query library
  • Loading branch information
SergeiPatiakin authored Aug 9, 2023
2 parents 4307747 + 1bdb1ea commit 4b903cc
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 97 deletions.
68 changes: 66 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dobkapapp",
"version": "0.3.1",
"version": "0.3.2",
"description": "Desktop application to automate dividend tax filings",
"main": ".webpack/main",
"scripts": {
Expand Down Expand Up @@ -67,6 +67,7 @@
"@fontsource/roboto": "^4.5.8",
"@mui/icons-material": "^5.11.0",
"@mui/material": "^5.11.3",
"@tanstack/react-query": "^4.32.6",
"better-sqlite3": "^8.0.1",
"dobkap": "^0.17.0",
"electron-squirrel-startup": "^1.0.0",
Expand Down
112 changes: 53 additions & 59 deletions src/renderer/components/Application.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ipcContextApi from '../ipc-context-api'
import React, { useEffect, useState } from 'react'
import React, { useEffect, useMemo, useState } from 'react'
import { AppBar, Button, CssBaseline, ListItemIcon, ListItemText, Menu, MenuItem, Toolbar } from '@mui/material'
import { TaxpayerProfilePage } from './TaxpayerProfilePage'
import { DevPage } from './DevPage'
Expand All @@ -12,14 +12,15 @@ import SyncIcon from '@mui/icons-material/Sync'
import EngineeringIcon from '@mui/icons-material/Engineering'
import SummarizeIcon from '@mui/icons-material/Summarize'
import CableIcon from '@mui/icons-material/Cable'
import { Filing, Mailbox, Report, TechnicalConf, TaxpayerProfile, Importer } from '../../common/ipc-types'
import { TechnicalConf, Importer } from '../../common/ipc-types'
import { fireAndForget } from '../../common/helpers'
import { FilingsPage } from './FilingsPage'
import { MailboxPage } from './MailboxPage'
import { SyncPage } from './SyncPage'
import { TechnicalPage } from './TechnicalPage'
import { ReportsPage } from './ReportsPage'
import { ImportersPage } from './ImportersPage'
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query'

type NavigationPage =
| 'settings.taxpayer'
Expand All @@ -34,62 +35,48 @@ type NavigationPage =
const Application: React.FC = () => {
const [navigationPage, setNavigationPage] = useState<NavigationPage>('sync')
const [navigationEnabled, setNavigationEnabled] = useState<boolean>(true)
const [reports, setReports] = useState<Array<Report>>([])
const [reportsTag, setReportsTag] = useState(Math.random())
const invalidateReports = () => setReportsTag(Math.random())

const reportsQuery = useQuery({
queryKey: ['reports'],
queryFn: () => ipcContextApi.getReports(),
})

const [filings, setFilings] = useState<Array<Filing>>([])
const [filingsTag, setFilingsTag] = useState(Math.random())
const invalidateFilings = () => setFilingsTag(Math.random())
const filingsQuery = useQuery({
queryKey: ['filings'],
queryFn: () => ipcContextApi.getFilings()
})

const [taxpayerProfile, setTaxpayerProfile] = useState<TaxpayerProfile | null>()
const [taxpayerProfileTag, setTaxpayerProfileTag] = useState(Math.random())
const invalidateTaxpayerProfile = () => setTaxpayerProfileTag(Math.random())
const taxpayerProfileQuery = useQuery({
queryKey: ['taxpayer-profile'],
queryFn: () => ipcContextApi.getTaxpayerProfile()
})

const [mailbox, setMailbox] = useState<Mailbox | null>()
const [mailboxTag, setMailboxTag] = useState(Math.random())
const invalidateMailbox = () => setMailboxTag(Math.random())
const mailboxQuery = useQuery({
queryKey: ['mailbox'],
queryFn: () => ipcContextApi.getMailbox()
})

const [technicalConf, setTechnicalConf] = useState<TechnicalConf | null>()
const [technicalConfTag, setTechnicalConfTag] = useState(Math.random())
const invalideTechnicalConf = () => setTechnicalConfTag(Math.random())

const [importers, setImporters] = useState<Array<Importer>>([])
const [importersTag, setImportersTag] = useState(Math.random())
const invalidateImporters = () => setImportersTag(Math.random())
const technicalConfQuery = useQuery({
queryKey: ['technical-conf'],
queryFn: () => ipcContextApi.getTechnicalConf()
})

const importersQuery = useQuery({
queryKey: ['importers'],
queryFn: () => ipcContextApi.getImporters()
})

const [menuAnchorEl, setMenuAnchorEl] = React.useState<HTMLElement | null>(null)
const menuOpen = Boolean(menuAnchorEl)

useEffect(() => fireAndForget(async () => {
setReports(await ipcContextApi.getReports())
}), [reportsTag])
useEffect(() => fireAndForget(async () => {
setFilings(await ipcContextApi.getFilings())
}), [filingsTag])
useEffect(() => fireAndForget(async () => {
setTaxpayerProfile(await ipcContextApi.getTaxpayerProfile())
}), [taxpayerProfileTag])
useEffect(() => fireAndForget(async () => {
setMailbox(await ipcContextApi.getMailbox())
}), [mailboxTag])
useEffect(() => fireAndForget(async () => {
setTechnicalConf(await ipcContextApi.getTechnicalConf())
}), [technicalConfTag])
useEffect(() => fireAndForget(async () => {
setImporters(await ipcContextApi.getImporters())
}), [importersTag])

const invalidateAllData = () => {
invalidateReports()
invalidateFilings()
invalidateTaxpayerProfile()
invalidateMailbox()
invalideTechnicalConf()
invalidateImporters()
}

if (!taxpayerProfile || !mailbox || !technicalConf) {
if (
!taxpayerProfileQuery.isSuccess ||
!mailboxQuery.isSuccess ||
!technicalConfQuery.isSuccess ||
!reportsQuery.isSuccess ||
!filingsQuery.isSuccess ||
!importersQuery.isSuccess
) {
return <>
<CssBaseline />
<p>Loading</p>
Expand Down Expand Up @@ -195,24 +182,31 @@ const Application: React.FC = () => {
{(() => {
switch (navigationPage) {
case 'settings.taxpayer':
return <TaxpayerProfilePage taxpayerProfile={taxpayerProfile} invalidateTaxpayerProfile={invalidateTaxpayerProfile} />
return <TaxpayerProfilePage taxpayerProfile={taxpayerProfileQuery.data} />
case 'settings.mailbox':
return <MailboxPage mailbox={mailbox} invalidateMailbox={invalidateMailbox} />
return <MailboxPage mailbox={mailboxQuery.data} />
case 'settings.technical':
return <TechnicalPage technicalConf={technicalConf} invalidateTechnicalConf={invalideTechnicalConf} />
return <TechnicalPage technicalConf={technicalConfQuery.data} />
case 'settings.importers':
return <ImportersPage importers={importers} invalidateImporters={invalidateImporters} />
return <ImportersPage importers={importersQuery.data} />
case 'sync':
return <SyncPage setNavigationEnabled={setNavigationEnabled} invalidateReports={invalidateReports} invalidateFilings={invalidateFilings} invalidateMailbox={invalidateMailbox} />
return <SyncPage setNavigationEnabled={setNavigationEnabled} />
case 'reports':
return <ReportsPage reports={reports} filings={filings} invalidateFilings={invalidateFilings} invalidateReports={invalidateReports} />
return <ReportsPage reports={reportsQuery.data} filings={filingsQuery.data} />
case 'filings':
return <FilingsPage reports={reports} filings={filings} invalidateFilings={invalidateFilings} />
return <FilingsPage reports={reportsQuery.data} filings={filingsQuery.data} />
case 'dev':
return <DevPage invalidateAllData={invalidateAllData} />
return <DevPage />
}
})()}
</>
}

export default Application
const ApplicationWrapper = () => {
const queryClient = useMemo(() => new QueryClient(), [])
return <QueryClientProvider client={queryClient}>
<Application/>
</QueryClientProvider>
}

export default ApplicationWrapper
9 changes: 5 additions & 4 deletions src/renderer/components/DevPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import React, { useEffect, useState } from 'react'
import { Accordion, AccordionDetails, AccordionSummary, Alert, Button, ButtonGroup, Container, Stack, Table, TableBody, TableCell, TableHead, TableRow, TextField, Typography } from '@mui/material'
import ipcContextApi from '../ipc-context-api'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import { useQueryClient } from '@tanstack/react-query'

type Props = {
invalidateAllData: () => void
}
// eslint-disable-next-line @typescript-eslint/ban-types
type Props = {}

export const DevPage = (props: Props) => {
const queryClient = useQueryClient()
const [sql, setSql] = useState('')
const [result, setResult] = useState<{columns: Array<{name: string}>, rows: any[][]} | null>(null)
const [errorMessage, setErrorMessage] = useState<string | null>(null)
Expand Down Expand Up @@ -46,7 +47,7 @@ export const DevPage = (props: Props) => {
onClick={async () => {
try {
const x = await ipcContextApi.runSql(sql)
props.invalidateAllData()
queryClient.invalidateQueries() // invalidate all data
setResult(x)
setErrorMessage(null)
} catch (e) {
Expand Down
5 changes: 3 additions & 2 deletions src/renderer/components/FilingEditDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import {
} from '@mui/material'
import ipcContextApi from '../../renderer/ipc-context-api'
import React, { useState } from 'react'
import { useQueryClient } from '@tanstack/react-query'

type FilingEditDialogProps = {
filing: Filing
onClose: () => void
invalidateFilings: () => void
}

export const FilingEditDialog = (props: FilingEditDialogProps) => {
const queryClient = useQueryClient()
const [paymentReference, setPaymentReference] = useState(props.filing.taxPaymentReference)
return <Dialog
open
Expand Down Expand Up @@ -61,7 +62,7 @@ export const FilingEditDialog = (props: FilingEditDialogProps) => {
...props.filing,
taxPaymentReference: paymentReference,
})
props.invalidateFilings()
queryClient.invalidateQueries({ queryKey: ['filings'] })
props.onClose()
}} autoFocus>
Save
Expand Down
8 changes: 3 additions & 5 deletions src/renderer/components/FilingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,23 @@ import DownloadIcon from '@mui/icons-material/Download'
import TrashIcon from '@mui/icons-material/Delete'
import EditIcon from '@mui/icons-material/Edit'
import { FilingEditDialog } from './FilingEditDialog'
import { useQueryClient } from '@tanstack/react-query'

interface FilingsPageProps {
reports: Array<Report>
filings: Array<Filing>
invalidateFilings: () => void
}

const PAGE_SIZE = 20

type FilingsRowProps = {
filing: Filing
openFilingEditDialog: () => void
invalidateFilings: () => void
}

const FilingsRow = (props: FilingsRowProps) => {
const theme = useTheme()
const queryClient = useQueryClient()
const [menuAnchorEl, setMenuAnchorEl] = React.useState<HTMLElement | null>(null)
const menuOpen = Boolean(menuAnchorEl)
return <TableRow>
Expand All @@ -55,7 +55,7 @@ const FilingsRow = (props: FilingsRowProps) => {
onChange={async e => {
const newStatus = e.target.value as FilingStatus
await ipcContextApi.updateFiling({...props.filing, status: newStatus})
props.invalidateFilings()
queryClient.invalidateQueries({ queryKey: ['filings'] })
}
}>
<MenuItem value='init'>Initial</MenuItem>
Expand Down Expand Up @@ -160,7 +160,6 @@ export const FilingsPage = (props: FilingsPageProps) => {
{filingEditDialogState.visible &&
<FilingEditDialog
filing={filingEditDialogState.filing}
invalidateFilings={props.invalidateFilings}
onClose={() => setFilingEditDialogState({ visible: false })}
/>
}
Expand Down Expand Up @@ -188,7 +187,6 @@ export const FilingsPage = (props: FilingsPageProps) => {
<FilingsRow
key={f.id}
filing={f}
invalidateFilings={props.invalidateFilings}
openFilingEditDialog={() => setFilingEditDialogState({
visible: true,
filing: f,
Expand Down
Loading

0 comments on commit 4b903cc

Please sign in to comment.