fix: invalidate queries better

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-10-17 11:01:20 +02:00
parent 4ccabc5fa3
commit c8bea685db
50 changed files with 355 additions and 129 deletions

View File

@@ -1,5 +1,3 @@
'use client';
import {
BatteryFullIcon,
BatteryLowIcon,

View File

@@ -1,5 +1,3 @@
'use client';
import { AnimatePresence, motion } from 'framer-motion';
import { useEffect, useState } from 'react';

View File

@@ -1,5 +1,3 @@
'use client';
import { getGithubRepoInfo } from '@/lib/github';
import Link from 'next/link';
import { useEffect, useState } from 'react';

View File

@@ -1,5 +1,3 @@
'use client';
import { cn } from '@/lib/utils';
import { motion } from 'framer-motion';
import NextImage from 'next/image';

View File

@@ -1,5 +1,3 @@
'use client';
import { motion, useScroll, useTransform } from 'framer-motion';
import { WorldMap } from './world-map';

View File

@@ -1,5 +1,3 @@
'use client';
import { baseOptions } from '@/app/layout.config';
import { cn } from '@/lib/utils';
import { AnimatePresence, motion } from 'framer-motion';

View File

@@ -1,4 +1,3 @@
'use client';
import NumberFlow from '@number-flow/react';
import { cn } from '@/lib/utils';

View File

@@ -1,5 +1,3 @@
'use client';
import { AnimatePresence, motion } from 'framer-motion';
import {
BellIcon,

View File

@@ -1,5 +1,3 @@
'use client';
import { motion } from 'framer-motion';
import { useEffect, useState } from 'react';

View File

@@ -1,5 +1,3 @@
'use client';
import Image from 'next/image';
import { useEffect, useState } from 'react';

View File

@@ -1,5 +1,3 @@
'use client';
import { SimpleChart } from '@/components/simple-chart';
import { cn } from '@/lib/utils';
import NumberFlow from '@number-flow/react';

View File

@@ -1,5 +1,3 @@
'use client';
import * as AccordionPrimitive from '@radix-ui/react-accordion';
import { ChevronDown } from 'lucide-react';
import type * as React from 'react';

View File

@@ -1,5 +1,3 @@
'use client';
import * as SliderPrimitive from '@radix-ui/react-slider';
import * as React from 'react';

View File

@@ -1,5 +1,3 @@
'use client';
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
import type * as React from 'react';

View File

@@ -1,5 +1,3 @@
'use client';
import DottedMap from 'dotted-map/without-countries';
import { useEffect, useMemo, useState } from 'react';
import { mapJsonString } from './world-map-string';

View File

@@ -3,6 +3,7 @@
"private": true,
"type": "module",
"scripts": {
"testing": "pnpm dev",
"dev": "pnpm with-env vite dev --port 3000",
"start_deprecated": "pnpm with-env node .output/server/index.mjs",
"preview": "vite preview",

View File

@@ -1,9 +1,12 @@
import type { UseQueryResult } from '@tanstack/react-query';
import { Button } from '@/components/ui/button';
import { DataTable } from '@/components/ui/data-table/data-table';
import { DataTableToolbar } from '@/components/ui/data-table/data-table-toolbar';
import { useTable } from '@/components/ui/data-table/use-table';
import { pushModal } from '@/modals';
import type { RouterOutputs } from '@/trpc/client';
import { PlusIcon } from 'lucide-react';
import { useColumns } from './columns';
type Props = {
@@ -23,7 +26,15 @@ export const ClientsTable = ({ query }: Props) => {
return (
<>
<DataTableToolbar table={table} />
<DataTableToolbar table={table}>
<Button
icon={PlusIcon}
responsive
onClick={() => pushModal('AddClient')}
>
Create client
</Button>
</DataTableToolbar>
<DataTable table={table} loading={isLoading} />
</>
);

View File

@@ -16,6 +16,7 @@ export function FeedbackButton() {
(window.uj as any).identify({
id: context.session?.userId,
firstName: context.session?.user?.firstName,
email: context.session?.user?.email,
});
(window.uj as any).showWidget();
}

View File

@@ -1,5 +1,3 @@
'use client';
import { Button } from '@/components/ui/button';
import {
Dialog,

View File

@@ -1,5 +1,3 @@
'use client';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { Widget, WidgetBody, WidgetHead } from '@/components/widget';

View File

@@ -1,12 +1,9 @@
'use client';
import { InputWithLabel, WithLabel } from '@/components/forms/input-with-label';
import { Button } from '@/components/ui/button';
import { Widget, WidgetBody, WidgetHead } from '@/components/widget';
import { useTRPC } from '@/integrations/trpc/react';
import { handleError } from '@/trpc/client';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from '@tanstack/react-router';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { Controller, useForm } from 'react-hook-form';
import { toast } from 'sonner';
import type { z } from 'zod';
@@ -24,8 +21,6 @@ interface EditOrganizationProps {
export default function EditOrganization({
organization,
}: EditOrganizationProps) {
const router = useRouter();
const { register, handleSubmit, formState, reset, control } = useForm<IForm>({
defaultValues: {
id: organization.id,
@@ -35,6 +30,7 @@ export default function EditOrganization({
});
const trpc = useTRPC();
const queryClient = useQueryClient();
const mutation = useMutation(
trpc.organization.update.mutationOptions({
onSuccess(res: any) {
@@ -45,7 +41,7 @@ export default function EditOrganization({
...res,
timezone: res.timezone!,
});
router.invalidate();
queryClient.invalidateQueries(trpc.organization.get.pathFilter());
},
onError: handleError,
}),

View File

@@ -1,5 +1,3 @@
'use client';
import type { IServiceOrganization } from '@openpanel/db';
import EditOrganization from './edit-organization';

View File

@@ -1,5 +1,3 @@
'use client';
import {
X_AXIS_STYLE_PROPS,
useXAxisProps,

View File

@@ -1,5 +1,3 @@
'use client';
import { Button } from '@/components/ui/button';
import { Widget } from '@/components/widget';
import { useTRPC } from '@/integrations/trpc/react';

View File

@@ -1,5 +1,3 @@
'use client';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,

View File

@@ -1,5 +1,3 @@
'use client';
import { useTRPC } from '@/integrations/trpc/react';
import { useQuery } from '@tanstack/react-query';
import { AnimatePresence, motion } from 'framer-motion';

View File

@@ -1,5 +1,3 @@
'use client';
import { useNumber } from '@/hooks/use-numer-formatter';
import { useTRPC } from '@/integrations/trpc/react';
import { countries } from '@/translations/countries';

View File

@@ -1,5 +1,3 @@
'use client';
import { useNumber } from '@/hooks/use-numer-formatter';
import { useTRPC } from '@/integrations/trpc/react';
import { useQuery } from '@tanstack/react-query';

View File

@@ -1,5 +1,3 @@
'use client';
import { useNumber } from '@/hooks/use-numer-formatter';
import { useTRPC } from '@/integrations/trpc/react';
import { useQuery } from '@tanstack/react-query';

View File

@@ -1,5 +1,3 @@
'use client';
import useWS from '@/hooks/use-ws';
import { useTRPC } from '@/integrations/trpc/react';
import { useQueryClient } from '@tanstack/react-query';

View File

@@ -1,12 +1,10 @@
'use client';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { Widget, WidgetBody, WidgetHead } from '@/components/widget';
import { handleError, useTRPC } from '@/integrations/trpc/react';
import { showConfirm } from '@/modals';
import type { IServiceProjectWithClients } from '@openpanel/db';
import { useMutation } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useRouter } from '@tanstack/react-router';
import { addHours, format, startOfHour } from 'date-fns';
import { TrashIcon } from 'lucide-react';
@@ -18,12 +16,17 @@ export default function DeleteProject({ project }: Props) {
const router = useRouter();
const trpc = useTRPC();
const queryClient = useQueryClient();
const mutation = useMutation(
trpc.project.delete.mutationOptions({
onError: handleError,
onSuccess: () => {
toast.success('Project updated');
router.invalidate();
toast.success('Project is scheduled for deletion');
queryClient.invalidateQueries(
trpc.project.getProjectWithClients.queryFilter({
projectId: project.id,
}),
);
},
}),
);
@@ -32,8 +35,12 @@ export default function DeleteProject({ project }: Props) {
trpc.project.cancelDeletion.mutationOptions({
onError: handleError,
onSuccess: () => {
toast.success('Project updated');
router.invalidate();
toast.success('Project deletion cancelled');
queryClient.invalidateQueries(
trpc.project.getProjectWithClients.queryFilter({
projectId: project.id,
}),
);
},
}),
);

View File

@@ -1,5 +1,3 @@
'use client';
import AnimateHeight from '@/components/animate-height';
import { InputWithLabel, WithLabel } from '@/components/forms/input-with-label';
import TagInput from '@/components/forms/tag-input';
@@ -13,7 +11,7 @@ import { handleError, useTRPC } from '@/integrations/trpc/react';
import { zodResolver } from '@hookform/resolvers/zod';
import type { IServiceProjectWithClients } from '@openpanel/db';
import { zProject } from '@openpanel/validation';
import { useMutation } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { SaveIcon } from 'lucide-react';
import { useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
@@ -44,11 +42,22 @@ export default function EditProjectDetails({ project }: Props) {
},
});
const trpc = useTRPC();
const queryClient = useQueryClient();
const mutation = useMutation(
trpc.project.update.mutationOptions({
onError: handleError,
onSuccess: () => {
toast.success('Project updated');
queryClient.invalidateQueries(
trpc.project.list.queryFilter({
organizationId: project.organizationId,
}),
);
queryClient.invalidateQueries(
trpc.project.getProjectWithClients.queryFilter({
projectId: project.id,
}),
);
},
}),
);

View File

@@ -1,5 +1,3 @@
'use client';
import { WithLabel } from '@/components/forms/input-with-label';
import TagInput from '@/components/forms/tag-input';
import { Button } from '@/components/ui/button';

View File

@@ -1,5 +1,3 @@
'use client';
import { Command as CommandPrimitive } from 'cmdk';
import { SearchIcon } from 'lucide-react';
import type * as React from 'react';

View File

@@ -1,5 +1,3 @@
'use client';
import type { Column } from '@tanstack/react-table';
import {
ChevronDown,

View File

@@ -1,5 +1,3 @@
'use client';
import type { Column } from '@tanstack/react-table';
import { CalendarIcon, XCircle, XCircleIcon } from 'lucide-react';
import * as React from 'react';

View File

@@ -1,5 +1,3 @@
'use client';
import type { Column } from '@tanstack/react-table';
import {
Check,

View File

@@ -1,5 +1,3 @@
'use client';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';

View File

@@ -1,5 +1,3 @@
'use client';
import type { Column, Table } from '@tanstack/react-table';
import { SearchIcon, X, XIcon } from 'lucide-react';
import * as React from 'react';

View File

@@ -1,5 +1,3 @@
'use client';
import { Button } from '@/components/ui/button';
import {
Command,

View File

@@ -1,5 +1,3 @@
'use client';
import { format } from 'date-fns';
import { Button } from '@/components/ui/button';

View File

@@ -1,5 +1,3 @@
'use client';
import * as SelectPrimitive from '@radix-ui/react-select';
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react';
import type * as React from 'react';

View File

@@ -1,5 +1,3 @@
'use client';
import * as SliderPrimitive from '@radix-ui/react-slider';
import * as React from 'react';

View File

@@ -44,6 +44,9 @@ export default function AddClient() {
queryClient.invalidateQueries(
trpc.project.getProjectWithClients.pathFilter(),
);
queryClient.invalidateQueries(
trpc.client.list.queryFilter({ projectId }),
);
},
onError: handleError,
}),

View File

@@ -10,7 +10,7 @@ import { useTRPC } from '@/integrations/trpc/react';
import { handleError } from '@/integrations/trpc/react';
import { zodResolver } from '@hookform/resolvers/zod';
import { zOnboardingProject } from '@openpanel/validation';
import { useMutation } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from '@tanstack/react-router';
import {
MonitorIcon,
@@ -45,10 +45,14 @@ export default function AddProject() {
},
});
const trpc = useTRPC();
const queryClient = useQueryClient();
const mutation = useMutation(
trpc.project.create.mutationOptions({
onError: handleError,
onSuccess: (res) => {
queryClient.invalidateQueries(
trpc.project.list.queryFilter({ organizationId }),
);
toast.success('Project created', {
description: `${res.name}`,
action: {

View File

@@ -1,5 +1,3 @@
'use client';
import { InputWithLabel } from '@/components/forms/input-with-label';
import { Button } from '@/components/ui/button';
import { ComboboxAdvanced } from '@/components/ui/combobox-advanced';

View File

@@ -12,8 +12,8 @@
"gen:referrers": "jiti scripts/get-referrers.ts && biome format --write ./src/referrers/index.ts"
},
"dependencies": {
"@bull-board/api": "5.21.0",
"@bull-board/express": "5.21.0",
"@bull-board/api": "6.13.1",
"@bull-board/express": "6.13.1",
"@openpanel/common": "workspace:*",
"@openpanel/db": "workspace:*",
"@openpanel/email": "workspace:*",

View File

@@ -1,8 +1,6 @@
import { createBullBoard } from '@bull-board/api';
import { BullMQAdapter } from '@bull-board/api/bullMQAdapter';
import { ExpressAdapter } from '@bull-board/express';
import express from 'express';
import { createInitialSalts } from '@openpanel/db';
import {
cronQueue,
@@ -11,6 +9,7 @@ import {
notificationQueue,
sessionsQueue,
} from '@openpanel/queue';
import express from 'express';
import client from 'prom-client';
import { BullBoardGroupMQAdapter } from 'groupmq';
@@ -32,7 +31,7 @@ async function start() {
if (process.env.DISABLE_BULLBOARD === undefined) {
const serverAdapter = new ExpressAdapter();
serverAdapter.setBasePath('/');
createBullBoard({
({
queues: [
new BullBoardGroupMQAdapter(eventsGroupQueue) as any,
new BullMQAdapter(sessionsQueue),