feat(ui): automation settings start with everyday tabs and confirm risky actions
- Tabs ordered from everyday (suggestions, recurring tasks, labels) to technical (calendar sync, API keys, webhooks); the page opens on "Vorschläge" instead of Webhooks, and says in one sentence what it is. - Resetting a number counter, deactivating a label template and ending a recurring task now ask first and say plainly what happens. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
78325af1fe
commit
dff6c364c8
4 files changed
+38
-32
No files matched your search
@@ -12,6 +12,7 @@ import { AutomationRule, AutomationTriggerType } from "@/lib/automation/types";
|
|||||||
import { formatGeneratedNumber } from "@/lib/automation/number-format";
|
import { formatGeneratedNumber } from "@/lib/automation/number-format";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { ConfirmDialog } from "@/components/confirm-dialog";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
@@ -207,15 +208,16 @@ function RuleCard({ rule }: { rule: AutomationRule }) {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{numberFormatRule ? (
|
{numberFormatRule ? (
|
||||||
<Button
|
<ConfirmDialog
|
||||||
type="button"
|
triggerLabel="Zähler zurücksetzen"
|
||||||
variant="ghost"
|
triggerVariant="ghost"
|
||||||
size="sm"
|
triggerDisabled={resetMutation.isPending}
|
||||||
disabled={resetMutation.isPending}
|
title="Zähler zurücksetzen?"
|
||||||
onClick={() => resetMutation.mutate()}
|
description="Die nächste Nummer beginnt wieder bei 1. Gibt es im selben Zeitraum schon Nummern, können doppelte Los-/Chargennummern entstehen. Nur zurücksetzen, wenn ein neuer Zeitraum beginnt."
|
||||||
>
|
confirmLabel="Zurücksetzen"
|
||||||
{resetMutation.isPending ? "Wird zurückgesetzt…" : "Zähler zurücksetzen"}
|
isPending={resetMutation.isPending}
|
||||||
</Button>
|
onConfirm={() => resetMutation.mutate()}
|
||||||
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { toast } from "sonner";
|
|||||||
import { deactivateLabelTemplate, fetchLabelTemplates } from "@/lib/label-templates/api";
|
import { deactivateLabelTemplate, fetchLabelTemplates } from "@/lib/label-templates/api";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { ConfirmDialog } from "@/components/confirm-dialog";
|
||||||
import { EmptyState } from "@/components/empty-state";
|
import { EmptyState } from "@/components/empty-state";
|
||||||
import { EntityCard } from "@/components/entity-card";
|
import { EntityCard } from "@/components/entity-card";
|
||||||
|
|
||||||
@@ -74,15 +75,16 @@ export function LabelTemplatesTab() {
|
|||||||
<Pencil className="size-3.5" />
|
<Pencil className="size-3.5" />
|
||||||
Bearbeiten
|
Bearbeiten
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<ConfirmDialog
|
||||||
type="button"
|
triggerLabel="Deaktivieren"
|
||||||
variant="ghost"
|
triggerVariant="ghost"
|
||||||
size="sm"
|
triggerDisabled={deactivateMutation.isPending}
|
||||||
disabled={deactivateMutation.isPending}
|
title="Vorlage deaktivieren?"
|
||||||
onClick={() => deactivateMutation.mutate(template.id)}
|
description={`„${template.name}“ steht danach beim Etikettendruck nicht mehr zur Auswahl. Bereits gedruckte Etiketten bleiben unverändert.`}
|
||||||
>
|
confirmLabel="Deaktivieren"
|
||||||
Deaktivieren
|
isPending={deactivateMutation.isPending}
|
||||||
</Button>
|
onConfirm={() => deactivateMutation.mutate(template.id)}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -22,14 +22,15 @@ type Tab =
|
|||||||
| "calendar-sync"
|
| "calendar-sync"
|
||||||
| "api-keys";
|
| "api-keys";
|
||||||
|
|
||||||
|
// Everyday settings first, connections to other systems last.
|
||||||
const TABS: { value: Tab; label: string }[] = [
|
const TABS: { value: Tab; label: string }[] = [
|
||||||
{ value: "webhooks", label: "Webhooks" },
|
{ value: "rules", label: "Vorschläge" },
|
||||||
{ value: "task-templates", label: "Wiederkehrende Aufgaben" },
|
{ value: "task-templates", label: "Wiederkehrende Aufgaben" },
|
||||||
{ value: "label-templates", label: "Etikettenvorlagen" },
|
{ value: "label-templates", label: "Etikettenvorlagen" },
|
||||||
{ value: "social-media", label: "Stammdaten & Web" },
|
{ value: "social-media", label: "Stammdaten & Web" },
|
||||||
{ value: "rules", label: "Regeln" },
|
|
||||||
{ value: "calendar-sync", label: "Kalender-Sync" },
|
{ value: "calendar-sync", label: "Kalender-Sync" },
|
||||||
{ value: "api-keys", label: "API-Schlüssel" },
|
{ value: "api-keys", label: "API-Schlüssel" },
|
||||||
|
{ value: "webhooks", label: "Webhooks" },
|
||||||
];
|
];
|
||||||
|
|
||||||
function isTab(value: string | null): value is Tab {
|
function isTab(value: string | null): value is Tab {
|
||||||
@@ -39,7 +40,7 @@ function isTab(value: string | null): value is Tab {
|
|||||||
function AutomationPageContent() {
|
function AutomationPageContent() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const tab: Tab = isTab(searchParams.get("tab")) ? (searchParams.get("tab") as Tab) : "webhooks";
|
const tab: Tab = isTab(searchParams.get("tab")) ? (searchParams.get("tab") as Tab) : "rules";
|
||||||
|
|
||||||
function setTab(next: Tab) {
|
function setTab(next: Tab) {
|
||||||
router.replace(`/settings/automation?tab=${next}`);
|
router.replace(`/settings/automation?tab=${next}`);
|
||||||
@@ -50,7 +51,7 @@ function AutomationPageContent() {
|
|||||||
<PageHeader
|
<PageHeader
|
||||||
icon={Zap}
|
icon={Zap}
|
||||||
title="Automatisierung"
|
title="Automatisierung"
|
||||||
description="Webhooks, wiederkehrende Aufgaben, Etikettenvorlagen, Social Media, Regeln, Kalender-Sync und API-Schlüssel"
|
description="Was ApiCore dir abnimmt – und wie es mit anderen Systemen verbunden ist."
|
||||||
gradient="var(--gradient-sky)"
|
gradient="var(--gradient-sky)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { toast } from "sonner";
|
|||||||
import { deactivateTaskTemplate, fetchTaskTemplates } from "@/lib/task-templates/api";
|
import { deactivateTaskTemplate, fetchTaskTemplates } from "@/lib/task-templates/api";
|
||||||
import { TaskTemplate, TaskTemplateRecurrenceType } from "@/lib/task-templates/types";
|
import { TaskTemplate, TaskTemplateRecurrenceType } from "@/lib/task-templates/types";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { ConfirmDialog } from "@/components/confirm-dialog";
|
||||||
import { EmptyState } from "@/components/empty-state";
|
import { EmptyState } from "@/components/empty-state";
|
||||||
import { EntityCard } from "@/components/entity-card";
|
import { EntityCard } from "@/components/entity-card";
|
||||||
import { ActiveHistoryTabs, type EntityLifecycleTab } from "@/components/active-history-tabs";
|
import { ActiveHistoryTabs, type EntityLifecycleTab } from "@/components/active-history-tabs";
|
||||||
@@ -106,15 +106,16 @@ export function TaskTemplatesTab() {
|
|||||||
actions={
|
actions={
|
||||||
<>
|
<>
|
||||||
<EditTaskTemplateDialog template={template} />
|
<EditTaskTemplateDialog template={template} />
|
||||||
<Button
|
<ConfirmDialog
|
||||||
type="button"
|
triggerLabel="Deaktivieren"
|
||||||
variant="ghost"
|
triggerVariant="ghost"
|
||||||
size="sm"
|
triggerDisabled={!template.active || deactivateMutation.isPending}
|
||||||
disabled={!template.active || deactivateMutation.isPending}
|
title="Wiederkehrende Aufgabe beenden?"
|
||||||
onClick={() => deactivateMutation.mutate(template.id)}
|
description={`Für „${template.title}“ werden keine neuen Aufgaben mehr angelegt. Bereits angelegte Aufgaben bleiben in der Liste.`}
|
||||||
>
|
confirmLabel="Beenden"
|
||||||
Deaktivieren
|
isPending={deactivateMutation.isPending}
|
||||||
</Button>
|
onConfirm={() => deactivateMutation.mutate(template.id)}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in new issue
Block a user