- The domain {hostedDomain.domain} is currently pending because we could not confirm that it resolves to this server. No
- configuration changes have been made yet.
-
-
- If you force validate this domain, the server configuration will be updated regardless. However, this may impact your ability to generate
- an SSL certificate if the domain does not actually point to this server.
-
-
Are you sure you want to continue?
-
-
-
- Cancel
-
-
- {form.processing && }
-
- Force Validate
-
-
-
-
- );
-}
-
function CertificateCell({ row }: { row: HostedDomain }) {
const ssl = row.ssl as { id: number; type: string; domains: string[]; expires_at: string } | null;
const { ssl_method } = row;
@@ -215,6 +96,7 @@ export default function HostedDomains() {
hostedDomains: InertiaTableData;
hasSiteSsl: boolean;
}>();
+ const dialog = useDialog();
const sslLocked = !page.props.site.can_configure_ssl;
@@ -292,12 +174,10 @@ export default function HostedDomains() {
)}
-
-
-
- Add Domain
-
-
+ dialog.createHostedDomain.open({ site: page.props.site })}>
+
+ Add Domain
+
@@ -335,9 +215,7 @@ export default function HostedDomains() {
-
- e.preventDefault()}>Edit
-
+ dialog.editHostedDomain.open({ hostedDomain: hd })}>Edit
{hd.status === 'pending' && (
<>
@@ -354,7 +232,20 @@ export default function HostedDomains() {
>
Validate
-
+
+ dialog.confirm.open({
+ title: 'Force Validate Domain',
+ description: `The domain ${hd.domain} is currently pending because we could not confirm that it resolves to this server. If you force validate this domain, the server configuration will be updated regardless. This may impact your ability to generate an SSL certificate if the domain does not actually point to this server. Are you sure you want to continue?`,
+ variant: 'destructive',
+ confirmLabel: 'Force Validate',
+ method: 'post',
+ url: route('hosted-domains.force-activate', { server: hd.server_id, site: hd.site_id, hostedDomain: hd.id }),
+ })
+ }
+ >
+ Force Validate
+
>
)}
{!isPrimary && (hd.status === 'active' || hd.status === 'pending') && (
@@ -396,7 +287,21 @@ export default function HostedDomains() {
{!isPrimary && (
<>
-
+
+ dialog.confirm.open({
+ title: 'Delete Domain',
+ description: `Are you sure you want to delete ${hd.domain}?`,
+ variant: 'destructive',
+ confirmLabel: 'Delete',
+ method: 'delete',
+ url: route('hosted-domains.destroy', { server: hd.server_id, site: hd.site_id, hostedDomain: hd.id }),
+ })
+ }
+ >
+ Delete
+
>
)}
diff --git a/resources/js/pages/monitoring/components/actions.tsx b/resources/js/pages/monitoring/components/actions.tsx
index 3ffbd2592..60733a4b4 100644
--- a/resources/js/pages/monitoring/components/actions.tsx
+++ b/resources/js/pages/monitoring/components/actions.tsx
@@ -1,135 +1,14 @@
import { Server } from '@/types/server';
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
import { Button } from '@/components/ui/button';
-import { LoaderCircleIcon, MoreHorizontalIcon } from 'lucide-react';
-import React, { FormEvent, useState } from 'react';
-import {
- Dialog,
- DialogClose,
- DialogContent,
- DialogDescription,
- DialogFooter,
- DialogHeader,
- DialogTitle,
- DialogTrigger,
-} from '@/components/ui/dialog';
-import { Form, FormField, FormFields } from '@/components/ui/form';
-import { useForm, usePage } from '@inertiajs/react';
-import { Label } from '@/components/ui/label';
-import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
-import FormSuccessful from '@/components/form-successful';
-
-function DataRetention() {
- const page = usePage<{
- server: Server;
- dataRetention: string;
- }>();
- const [open, setOpen] = useState(false);
- const form = useForm({
- data_retention: String(page.props.dataRetention || '30'),
- });
-
- const submit = (e: FormEvent) => {
- e.preventDefault();
- form.patch(route('monitoring.update', page.props.server.id), {
- onSuccess: () => {
- setOpen(false);
- },
- preserveScroll: true,
- preserveState: true,
- });
- };
-
- return (
-
-
- e.preventDefault()}>Data retention
-
-
-
- Data retention
- Data retention
-
-
-
-
- Close
-
-
- {form.processing && }
- Save
-
-
-
-
- );
-}
-
-function Reset({ server }: { server: Server }) {
- const [open, setOpen] = useState(false);
- const form = useForm();
-
- const submit = () => {
- form.delete(route('monitoring.destroy', { server: server.id }), {
- onSuccess: () => {
- setOpen(false);
- },
- });
- };
- return (
-
-
- e.preventDefault()}>
- Reset
-
-
-
-
- Reset metrics
- Reset and delete metrics
-
-
- Are you sure you want to reset metrics? This will delete all existing monitoring metrics data for server {server.name} and
- cannot be undone.
-
-
-
- Cancel
-
-
- {form.processing && }
-
- Reset
-
-
-
-
- );
-}
+import { MoreHorizontalIcon } from 'lucide-react';
+import { usePage } from '@inertiajs/react';
+import { useDialog } from '@/hooks/use-dialog';
export default function Actions({ server }: { server: Server }) {
+ const dialog = useDialog();
+ const page = usePage<{ dataRetention: string }>();
+
return (
@@ -139,9 +18,25 @@ export default function Actions({ server }: { server: Server }) {
-
+ dialog.dataRetention.open({ server, dataRetention: page.props.dataRetention })}>
+ Data retention
+
-
+
+ dialog.confirm.open({
+ title: 'Reset metrics',
+ description: `Are you sure you want to reset metrics? This will delete all existing monitoring metrics data for server ${server.name} and cannot be undone.`,
+ variant: 'destructive',
+ confirmLabel: 'Reset',
+ method: 'delete',
+ url: route('monitoring.destroy', { server: server.id }),
+ })
+ }
+ >
+ Reset
+
);
diff --git a/resources/js/pages/monitoring/components/data-retention-dialog.tsx b/resources/js/pages/monitoring/components/data-retention-dialog.tsx
new file mode 100644
index 000000000..93a2e3027
--- /dev/null
+++ b/resources/js/pages/monitoring/components/data-retention-dialog.tsx
@@ -0,0 +1,74 @@
+import { Server } from '@/types/server';
+import { Button } from '@/components/ui/button';
+import { LoaderCircleIcon } from 'lucide-react';
+import { FormEvent } from 'react';
+import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
+import { Form, FormField, FormFields } from '@/components/ui/form';
+import { useForm } from '@inertiajs/react';
+import { Label } from '@/components/ui/label';
+import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
+
+type DataRetentionDialogProps = {
+ open: boolean;
+ onOpenChange: (open: boolean) => void;
+ server: Server;
+ dataRetention: string;
+};
+
+export default function DataRetentionDialog({ open, onOpenChange, server, dataRetention }: DataRetentionDialogProps) {
+ const form = useForm({
+ data_retention: String(dataRetention || '30'),
+ });
+
+ const submit = (e: FormEvent) => {
+ e.preventDefault();
+ form.patch(route('monitoring.update', server.id), {
+ onSuccess: () => onOpenChange(false),
+ preserveScroll: true,
+ preserveState: true,
+ });
+ };
+
+ return (
+
+ e.preventDefault()}>
+
+ Data retention
+ Data retention
+
+
+
+
+ Close
+
+
+ {form.processing && }
+ Save
+
+
+
+
+ );
+}
diff --git a/resources/js/pages/notification-channels/components/delete.tsx b/resources/js/pages/notification-channels/components/delete.tsx
index 906d3c041..25cf8adf9 100644
--- a/resources/js/pages/notification-channels/components/delete.tsx
+++ b/resources/js/pages/notification-channels/components/delete.tsx
@@ -1,62 +1,25 @@
-import {
- Dialog,
- DialogClose,
- DialogContent,
- DialogDescription,
- DialogFooter,
- DialogHeader,
- DialogTitle,
- DialogTrigger,
-} from '@/components/ui/dialog';
import { DropdownMenuItem } from '@/components/ui/dropdown-menu';
-import { Button } from '@/components/ui/button';
-import { useForm } from '@inertiajs/react';
-import { LoaderCircleIcon } from 'lucide-react';
-import FormSuccessful from '@/components/form-successful';
-import { useState } from 'react';
-import InputError from '@/components/ui/input-error';
import { NotificationChannel } from '@/types/notification-channel';
+import { useDialog } from '@/hooks/use-dialog';
export default function Delete({ notificationChannel }: { notificationChannel: NotificationChannel }) {
- const [open, setOpen] = useState(false);
- const form = useForm();
+ const dialog = useDialog();
- const submit = () => {
- form.delete(route('notification-channels.destroy', notificationChannel.id), {
- onSuccess: () => {
- setOpen(false);
- },
- });
- };
return (
-
-
- e.preventDefault()}>
- Delete
-
-
-
-
- Delete {notificationChannel.name}
- Delete notification channel
-
-
-
- Are you sure you want to delete {notificationChannel.name}?
-