mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
fix: policies reload
This commit is contained in:
+2
-10
@@ -6,8 +6,6 @@ import {eq, and, inArray} from "drizzle-orm";
|
||||
import * as drizzleDb from "@/db";
|
||||
import {getOrganizationProjectDatabases} from "@/lib/services";
|
||||
import {getActiveMember, getOrganization} from "@/lib/auth/auth";
|
||||
import {getOrganizationChannels} from "@/db/services/notification-channel";
|
||||
import {getOrganizationStorageChannels} from "@/db/services/storage-channel";
|
||||
import {BackupModalProvider} from "@/components/wrappers/dashboard/database/backup/backup-modal-context";
|
||||
import {DatabaseContent} from "@/components/wrappers/dashboard/projects/database/database-content";
|
||||
|
||||
@@ -85,12 +83,6 @@ export default async function RoutePage(props: PageParams<{
|
||||
notFound();
|
||||
}
|
||||
|
||||
const organizationChannels = await getOrganizationChannels(organization.id);
|
||||
const activeOrganizationChannels = organizationChannels.filter(channel => channel.enabled);
|
||||
|
||||
const organizationStorageChannels = await getOrganizationStorageChannels(organization.id);
|
||||
const activeOrganizationStorageChannels = organizationStorageChannels.filter(channel => channel.enabled);
|
||||
|
||||
|
||||
const successRate = totalBackups > 0 ? (successfulBackups / totalBackups) * 100 : null;
|
||||
|
||||
@@ -110,8 +102,8 @@ export default async function RoutePage(props: PageParams<{
|
||||
availableBackups={availableBackups}
|
||||
successRate={successRate}
|
||||
organizationId={organization.id}
|
||||
activeOrganizationChannels={activeOrganizationChannels}
|
||||
activeOrganizationStorageChannels={activeOrganizationStorageChannels}
|
||||
activeOrganizationChannels={[]}
|
||||
activeOrganizationStorageChannels={[]}
|
||||
/>
|
||||
</BackupModalProvider>
|
||||
</Page>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import {useMutation, useQueryClient} from "@tanstack/react-query";
|
||||
import {useRouter} from "next/navigation";
|
||||
import {toast} from "sonner";
|
||||
|
||||
import {backupButtonAction} from "@/components/wrappers/dashboard/backup/backup-button/backup-button.action";
|
||||
@@ -15,6 +16,7 @@ export type BackupButtonProps = {
|
||||
|
||||
export const BackupButton = (props: BackupButtonProps) => {
|
||||
const queryClient = useQueryClient();
|
||||
const router = useRouter();
|
||||
const isMobile = useIsMobile()
|
||||
|
||||
const mutation = useMutation({
|
||||
@@ -23,6 +25,7 @@ export const BackupButton = (props: BackupButtonProps) => {
|
||||
if (backup?.data?.success) {
|
||||
toast.success(backup.data.actionSuccess?.message || "Backup created successfully!");
|
||||
queryClient.invalidateQueries({queryKey: ["database-data", props.databaseId]});
|
||||
router.refresh();
|
||||
} else {
|
||||
toast.error(backup?.serverError || "Failed to create backup.");
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import {TooltipProvider} from "@/components/ui/tooltip";
|
||||
import {getChannelIcon} from "@/components/wrappers/dashboard/admin/channels/helpers/common";
|
||||
import {Badge} from "@/components/ui/badge";
|
||||
import {getStatusColor, getStatusIcon} from "@/components/wrappers/dashboard/admin/notifications/logs/columns";
|
||||
import {useRouter} from "next/navigation";
|
||||
import {
|
||||
createRestorationBackupAction, deleteBackupAction, deleteBackupStorageAction,
|
||||
downloadBackupAction
|
||||
@@ -39,6 +40,7 @@ export const BackupActionsForm = ({backup, action}: BackupActionsFormProps) => {
|
||||
const filteredBackupStorages = backup.storages?.filter((storage) => storage.deletedAt === null) ?? []
|
||||
const {closeModal} = useBackupModal();
|
||||
const queryClient = useQueryClient();
|
||||
const router = useRouter();
|
||||
|
||||
const form = useZodForm({
|
||||
schema: BackupActionsSchema,
|
||||
@@ -72,6 +74,7 @@ export const BackupActionsForm = ({backup, action}: BackupActionsFormProps) => {
|
||||
if (inner?.success) {
|
||||
toast.success(inner.actionSuccess?.message);
|
||||
queryClient.invalidateQueries({queryKey: ["database-data", backup.databaseId]});
|
||||
router.refresh();
|
||||
if (action === "download") {
|
||||
const url = inner.value
|
||||
if (typeof url === "string") {
|
||||
@@ -89,6 +92,7 @@ export const BackupActionsForm = ({backup, action}: BackupActionsFormProps) => {
|
||||
if (action === "delete") {
|
||||
toast.success("Backup deleted successfully.")
|
||||
queryClient.invalidateQueries({queryKey: ["database-data", backup.databaseId]});
|
||||
router.refresh();
|
||||
closeModal()
|
||||
} else {
|
||||
toast.error(inner?.actionError?.message ?? "An error occurred.");
|
||||
@@ -110,6 +114,7 @@ export const BackupActionsForm = ({backup, action}: BackupActionsFormProps) => {
|
||||
if (inner?.success) {
|
||||
toast.success(inner.actionSuccess?.message);
|
||||
queryClient.invalidateQueries({queryKey: ["database-data", backup.databaseId]});
|
||||
router.refresh();
|
||||
closeModal()
|
||||
} else {
|
||||
toast.error(inner?.actionError?.message);
|
||||
|
||||
@@ -5,6 +5,8 @@ import {db} from "@/db";
|
||||
import {eq} from "drizzle-orm";
|
||||
import * as drizzleDb from "@/db";
|
||||
import {BackupWith, Restoration} from "@/db/schema/07_database";
|
||||
import {getOrganizationChannels} from "@/db/services/notification-channel";
|
||||
import {getOrganizationStorageChannels} from "@/db/services/storage-channel";
|
||||
|
||||
export const getDatabaseDataAction = userAction
|
||||
.schema(
|
||||
@@ -19,6 +21,9 @@ export const getDatabaseDataAction = userAction
|
||||
where: eq(drizzleDb.schemas.database.id, databaseId),
|
||||
with: {
|
||||
project: true,
|
||||
retentionPolicy: true,
|
||||
alertPolicies: true,
|
||||
storagePolicies: true
|
||||
}
|
||||
});
|
||||
|
||||
@@ -45,10 +50,23 @@ export const getDatabaseDataAction = userAction
|
||||
const successfulBackups = backups.filter(b => b.status === "success").length;
|
||||
const successRate = totalBackups > 0 ? (successfulBackups / totalBackups) * 100 : null;
|
||||
|
||||
let activeOrganizationChannels = [];
|
||||
let activeOrganizationStorageChannels = [];
|
||||
|
||||
if (database?.project?.organizationId) {
|
||||
const organizationChannels = await getOrganizationChannels(database.project.organizationId);
|
||||
activeOrganizationChannels = organizationChannels.filter(channel => channel.enabled);
|
||||
|
||||
const organizationStorageChannels = await getOrganizationStorageChannels(database.project.organizationId);
|
||||
activeOrganizationStorageChannels = organizationStorageChannels.filter(channel => channel.enabled);
|
||||
}
|
||||
|
||||
return {
|
||||
database,
|
||||
backups,
|
||||
restorations,
|
||||
activeOrganizationChannels,
|
||||
activeOrganizationStorageChannels,
|
||||
stats: {
|
||||
totalBackups,
|
||||
availableBackups,
|
||||
|
||||
@@ -14,6 +14,7 @@ import {Switch} from "@/components/ui/switch";
|
||||
import {Card} from "@/components/ui/card";
|
||||
import Link from "next/link";
|
||||
import {useIsMobile} from "@/hooks/use-mobile";
|
||||
import {useRouter} from "next/navigation";
|
||||
import {
|
||||
ChannelKind,
|
||||
getChannelIcon,
|
||||
@@ -48,6 +49,7 @@ export const ChannelPoliciesForm = ({
|
||||
kind
|
||||
}: ChannelPoliciesFormProps) => {
|
||||
const queryClient = useQueryClient();
|
||||
const router = useRouter();
|
||||
const isMobile = useIsMobile();
|
||||
const channelText = getChannelTextBasedOnKind(kind);
|
||||
|
||||
@@ -130,6 +132,7 @@ export const ChannelPoliciesForm = ({
|
||||
onSuccess: () => {
|
||||
toast.success("Policies saved successfully");
|
||||
queryClient.invalidateQueries({queryKey: ["database-data", database.id]});
|
||||
router.refresh();
|
||||
},
|
||||
onError: (error: any) => { toast.error(error.message || "Failed to save policies"); },
|
||||
});
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Label } from "@/components/ui/label";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { useState } from "react";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { toast } from "sonner";
|
||||
import { updateDatabaseBackupPolicyAction } from "@/components/wrappers/dashboard/database/cron-button/cron.action";
|
||||
import {Database} from "@/db/schema/07_database";
|
||||
@@ -18,6 +19,7 @@ export type CronButtonProps = {
|
||||
|
||||
export const CronButton = (props: CronButtonProps) => {
|
||||
const queryClient = useQueryClient();
|
||||
const router = useRouter();
|
||||
const [isSwitched, setIsSwitched] = useState(props.database.backupPolicy !== null);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
@@ -27,6 +29,7 @@ export const CronButton = (props: CronButtonProps) => {
|
||||
onSuccess: () => {
|
||||
toast.success(`Method updated successfully.`);
|
||||
queryClient.invalidateQueries({ queryKey: ["database-data", props.database.id] });
|
||||
router.refresh();
|
||||
},
|
||||
onError: () => {
|
||||
toast.error(`An error occurred while updating backup method.`);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {AdvancedCronSelect} from "./advanced-cron-select";
|
||||
import {updateDatabaseBackupPolicyAction} from "@/components/wrappers/dashboard/database/cron-button/cron.action";
|
||||
import {useMutation, useQueryClient} from "@tanstack/react-query";
|
||||
import {useRouter} from "next/navigation";
|
||||
import {useState} from "react";
|
||||
import {toast} from "sonner";
|
||||
import {Button} from "@/components/ui/button";
|
||||
@@ -15,6 +16,7 @@ export type CronInputProps = {
|
||||
export const CronInput = ({database, onSuccess}: CronInputProps) => {
|
||||
const [cron, setCron] = useState<string>(database.backupPolicy ?? "* * * * *");
|
||||
const queryClient = useQueryClient();
|
||||
const router = useRouter();
|
||||
|
||||
const updateBackupPolicy = useMutation({
|
||||
mutationFn: (value: string) => updateDatabaseBackupPolicyAction({databaseId: database.id, backupPolicy: value}),
|
||||
@@ -22,6 +24,7 @@ export const CronInput = ({database, onSuccess}: CronInputProps) => {
|
||||
toast.success(`Cron updated successfully.`);
|
||||
onSuccess?.()
|
||||
queryClient.invalidateQueries({queryKey: ["database-data", database.id]});
|
||||
router.refresh();
|
||||
},
|
||||
onError: () => {
|
||||
toast.error(`An error occurred while updating cron value.`);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import {DropZoneFile} from "@/components/wrappers/common/dropzone/dropzone-file";
|
||||
import {useMutation, useQueryClient} from "@tanstack/react-query";
|
||||
import {useRouter} from "next/navigation";
|
||||
import {useState} from "react";
|
||||
import {Loader2} from "lucide-react";
|
||||
import {ButtonWithLoading} from "@/components/wrappers/common/button/button-with-loading";
|
||||
@@ -16,6 +17,7 @@ type UploadRetentionZoneProps = {
|
||||
|
||||
export const UploadBackupZone = ({onSuccessAction, databaseId}: UploadRetentionZoneProps) => {
|
||||
const queryClient = useQueryClient();
|
||||
const router = useRouter();
|
||||
|
||||
const [isProcessing, setIsProcessing] = useState(false);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
@@ -37,6 +39,7 @@ export const UploadBackupZone = ({onSuccessAction, databaseId}: UploadRetentionZ
|
||||
toast.success(inner.actionSuccess?.message);
|
||||
onSuccessAction?.()
|
||||
queryClient.invalidateQueries({queryKey: ["database-data", databaseId]});
|
||||
router.refresh();
|
||||
} else {
|
||||
toast.error(inner?.actionError?.message);
|
||||
}
|
||||
|
||||
+3
@@ -11,6 +11,7 @@ import {
|
||||
} from "@/components/ui/form";
|
||||
import {RetentionSettings, RetentionSettingsSchema} from "./backup-retention-settings.schema";
|
||||
import {useMutation, useQueryClient} from "@tanstack/react-query";
|
||||
import {useRouter} from "next/navigation";
|
||||
import {updateOrCreateBackupRetentionPolicyAction} from "./backup-retention-settings.action";
|
||||
import {DatabaseWith, RetentionPolicy} from "@/db/schema/07_database";
|
||||
import {toast} from "sonner";
|
||||
@@ -28,6 +29,7 @@ export type BackupRetentionSettingsFormProps = {
|
||||
|
||||
export const BackupRetentionSettingsForm = ({defaultValues, database}: BackupRetentionSettingsFormProps) => {
|
||||
const queryClient = useQueryClient();
|
||||
const router = useRouter();
|
||||
|
||||
const defaultValuesFormatted: RetentionSettings = {
|
||||
type: defaultValues?.type,
|
||||
@@ -55,6 +57,7 @@ export const BackupRetentionSettingsForm = ({defaultValues, database}: BackupRet
|
||||
onSuccess: () => {
|
||||
toast.success("Retention policy updated successfully.");
|
||||
queryClient.invalidateQueries({queryKey: ["database-data", database.id]});
|
||||
router.refresh();
|
||||
},
|
||||
onError: () => {
|
||||
toast.error("An error occurred while updating retention policy.");
|
||||
|
||||
@@ -50,6 +50,8 @@ export const DatabaseContent = (props: DatabaseContentProps) => {
|
||||
},
|
||||
backups: props.backups,
|
||||
restorations: props.restorations,
|
||||
activeOrganizationChannels: props.activeOrganizationChannels,
|
||||
activeOrganizationStorageChannels: props.activeOrganizationStorageChannels,
|
||||
stats: {
|
||||
totalBackups: props.totalBackups,
|
||||
availableBackups: props.availableBackups,
|
||||
@@ -64,6 +66,8 @@ export const DatabaseContent = (props: DatabaseContentProps) => {
|
||||
const database = data?.database ?? props.database;
|
||||
const backups = data?.backups ?? props.backups;
|
||||
const restorations = data?.restorations ?? props.restorations;
|
||||
const activeOrganizationChannels = data?.activeOrganizationChannels ?? props.activeOrganizationChannels;
|
||||
const activeOrganizationStorageChannels = data?.activeOrganizationStorageChannels ?? props.activeOrganizationStorageChannels;
|
||||
const stats = data?.stats ?? {
|
||||
totalBackups: props.totalBackups,
|
||||
availableBackups: props.availableBackups,
|
||||
@@ -91,14 +95,14 @@ export const DatabaseContent = (props: DatabaseContentProps) => {
|
||||
database={database}
|
||||
kind={"notification"}
|
||||
icon={<Megaphone/>}
|
||||
channels={props.activeOrganizationChannels}
|
||||
channels={activeOrganizationChannels}
|
||||
organizationId={props.organizationId}
|
||||
/>
|
||||
<ChannelPoliciesModal
|
||||
database={database}
|
||||
icon={<HardDrive/>}
|
||||
kind={"storage"}
|
||||
channels={props.activeOrganizationStorageChannels}
|
||||
channels={activeOrganizationStorageChannels}
|
||||
organizationId={props.organizationId}
|
||||
/>
|
||||
<ImportModal database={database}/>
|
||||
|
||||
Reference in New Issue
Block a user