Optimised cach usage, and enforced maker checker
This commit is contained in:
@@ -47,6 +47,7 @@ import { ExportButton } from '../components/ui/ExportButton';
|
||||
import { ExportColumn } from '../utils/exportUtils';
|
||||
import { useTableSort, SortableTh } from '../utils/tableSort';
|
||||
import { useRbac } from '../auth/rbac';
|
||||
import { bumpMutationEpoch } from '../services/httpClient';
|
||||
import {
|
||||
Award,
|
||||
Budget,
|
||||
@@ -233,6 +234,7 @@ export const GrantsPage: React.FC = () => {
|
||||
const updateAwardMutation = useMutation({
|
||||
mutationFn: (data: UpdateAwardRequest) => updateAward(data),
|
||||
onSuccess: () => {
|
||||
bumpMutationEpoch();
|
||||
queryClient.invalidateQueries({ queryKey: ['awards'] });
|
||||
queryClient.invalidateQueries({ queryKey: ['dashboard'] });
|
||||
success('Award Updated', 'Award details saved successfully.');
|
||||
@@ -248,6 +250,7 @@ export const GrantsPage: React.FC = () => {
|
||||
const budgetMutation = useMutation({
|
||||
mutationFn: (data: CreateBudgetRequest) => createBudget(data),
|
||||
onSuccess: () => {
|
||||
bumpMutationEpoch();
|
||||
queryClient.invalidateQueries({ queryKey: ['budgets'] });
|
||||
success('Budget line established', 'Budget line created against project');
|
||||
setIsBudgetModalOpen(false);
|
||||
@@ -261,6 +264,7 @@ export const GrantsPage: React.FC = () => {
|
||||
const updateBudgetMutation = useMutation({
|
||||
mutationFn: (data: UpdateBudgetRequest) => updateBudget(data),
|
||||
onSuccess: () => {
|
||||
bumpMutationEpoch();
|
||||
queryClient.invalidateQueries({ queryKey: ['budgets'] });
|
||||
success('Budget Updated', 'Budget compliance and approval status updated.');
|
||||
setIsEditBudgetModalOpen(false);
|
||||
@@ -287,6 +291,7 @@ export const GrantsPage: React.FC = () => {
|
||||
});
|
||||
},
|
||||
onSuccess: () => {
|
||||
bumpMutationEpoch();
|
||||
queryClient.invalidateQueries({ queryKey: ['disbursements'] });
|
||||
success(
|
||||
editingDisbursement ? 'Disbursement Updated' : 'Disbursement Scheduled',
|
||||
@@ -497,6 +502,7 @@ export const GrantsPage: React.FC = () => {
|
||||
const approveMutation = useMutation({
|
||||
mutationFn: (id: string | number) => approveDisbursement(id),
|
||||
onSuccess: () => {
|
||||
bumpMutationEpoch();
|
||||
queryClient.invalidateQueries({ queryKey: ['disbursements'] });
|
||||
queryClient.invalidateQueries({ queryKey: ['dashboard'] });
|
||||
success(
|
||||
@@ -826,8 +832,10 @@ export const GrantsPage: React.FC = () => {
|
||||
<div className="flex items-center gap-2 self-end sm:self-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
refetchAwards();
|
||||
onClick={async () => {
|
||||
bumpMutationEpoch();
|
||||
await queryClient.invalidateQueries({ queryKey: ['awards'] });
|
||||
await refetchAwards();
|
||||
success('Refreshed', 'Awards intake list refreshed from API.');
|
||||
}}
|
||||
disabled={isFetchingAwards}
|
||||
@@ -919,10 +927,10 @@ export const GrantsPage: React.FC = () => {
|
||||
{Number(awd.status) === ApprovalStatus.Approved ? (
|
||||
<span
|
||||
className="inline-flex items-center gap-1 text-xs font-semibold text-emerald-400 bg-emerald-500/10 px-2.5 py-1.5 rounded-lg border border-emerald-500/20 cursor-default"
|
||||
title="Approved award is immutable. Details cannot be modified."
|
||||
title="Approved award details cannot be modified."
|
||||
>
|
||||
<Lock className="w-3 h-3 text-emerald-400" />
|
||||
<span>Approved (Immutable)</span>
|
||||
<span>Approved</span>
|
||||
</span>
|
||||
) : (
|
||||
<button
|
||||
@@ -973,8 +981,10 @@ export const GrantsPage: React.FC = () => {
|
||||
<div className="flex items-center gap-2 self-end sm:self-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
refetchBudgets();
|
||||
onClick={async () => {
|
||||
bumpMutationEpoch();
|
||||
await queryClient.invalidateQueries({ queryKey: ['budgets'] });
|
||||
await refetchBudgets();
|
||||
success('Refreshed', 'Budget line categories refreshed from API.');
|
||||
}}
|
||||
disabled={isFetchingBudgets}
|
||||
@@ -1059,10 +1069,10 @@ export const GrantsPage: React.FC = () => {
|
||||
{Number(b.status) === ApprovalStatus.Approved ? (
|
||||
<span
|
||||
className="inline-flex items-center gap-1 text-xs font-semibold text-emerald-400 bg-emerald-500/10 px-2.5 py-1.5 rounded-lg border border-emerald-500/20 cursor-default"
|
||||
title="Approved budget is immutable. Status cannot be modified."
|
||||
title="Approved budget status cannot be modified."
|
||||
>
|
||||
<Lock className="w-3 h-3 text-emerald-400" />
|
||||
<span>Approved (Immutable)</span>
|
||||
<span>Approved</span>
|
||||
</span>
|
||||
) : (
|
||||
<>
|
||||
@@ -1133,8 +1143,10 @@ export const GrantsPage: React.FC = () => {
|
||||
<div className="flex items-center gap-2 self-end sm:self-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
refetchDisbursements();
|
||||
onClick={async () => {
|
||||
bumpMutationEpoch();
|
||||
await queryClient.invalidateQueries({ queryKey: ['disbursements'] });
|
||||
await refetchDisbursements();
|
||||
success('Refreshed', 'Disbursement tranches refreshed from API.');
|
||||
}}
|
||||
disabled={isFetchingDisbursements}
|
||||
@@ -1549,7 +1561,7 @@ export const GrantsPage: React.FC = () => {
|
||||
onSubmit={editAwardForm.handleSubmit((values) => {
|
||||
if (!editingAward) return;
|
||||
if (Number(editingAward.status) === ApprovalStatus.Approved) {
|
||||
toastError('Record Immutable', 'Approved awards cannot be modified.');
|
||||
toastError('Record Approved', 'Approved awards cannot be modified.');
|
||||
return;
|
||||
}
|
||||
updateAwardMutation.mutate({
|
||||
@@ -1630,7 +1642,7 @@ export const GrantsPage: React.FC = () => {
|
||||
{Number(editingAward?.status) === ApprovalStatus.Approved ? (
|
||||
<div className="w-full px-3 py-2 text-xs border border-emerald-500/30 bg-emerald-500/10 rounded-xl text-emerald-300 font-semibold flex items-center gap-1.5 cursor-default">
|
||||
<Lock className="w-3.5 h-3.5 text-emerald-400" />
|
||||
<span>Approved (Immutable - Cannot Be Changed)</span>
|
||||
<span>Approved</span>
|
||||
</div>
|
||||
) : (
|
||||
<select
|
||||
@@ -1783,7 +1795,7 @@ export const GrantsPage: React.FC = () => {
|
||||
{Number(editingBudget?.status) === ApprovalStatus.Approved ? (
|
||||
<div className="w-full px-3 py-2 text-xs border border-emerald-500/30 bg-emerald-500/10 rounded-xl text-emerald-300 font-semibold flex items-center gap-1.5 cursor-default">
|
||||
<Lock className="w-3.5 h-3.5 text-emerald-400" />
|
||||
<span>Approved (Immutable - Status Cannot Be Changed)</span>
|
||||
<span>Approved</span>
|
||||
</div>
|
||||
) : (
|
||||
<select
|
||||
|
||||
Reference in New Issue
Block a user