aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/app/settings/rules/page.tsx
blob: 98a30bcc509c2f97b928727e770683f11517c3cc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"use client";

import { useState } from "react";
import { RuleEditor } from "@/components/dashboard/rules/RuleEngineRuleEditor";
import RuleList from "@/components/dashboard/rules/RuleEngineRuleList";
import { Button } from "@/components/ui/button";
import { FullPageSpinner } from "@/components/ui/full-page-spinner";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { Tooltip, TooltipContent, TooltipTrigger } from "components/ui/tooltip";
import { FlaskConical, PlusCircle } from "lucide-react";

import { RuleEngineRule } from "@karakeep/shared/types/rules";

export default function RulesSettingsPage() {
  const { t } = useTranslation();
  const [editingRule, setEditingRule] = useState<
    (Omit<RuleEngineRule, "id"> & { id: string | null }) | null
  >(null);

  const { data: rules, isLoading } = api.rules.list.useQuery(undefined, {
    refetchOnWindowFocus: true,
    refetchOnMount: true,
  });

  const handleCreateRule = () => {
    const newRule = {
      id: null,
      name: "New Rule",
      description: "Description of the new rule",
      enabled: true,
      event: { type: "bookmarkAdded" as const },
      condition: { type: "alwaysTrue" as const },
      actions: [{ type: "addTag" as const, tagId: "" }],
    };
    setEditingRule(newRule);
  };

  const handleDeleteRule = (ruleId: string) => {
    if (editingRule?.id === ruleId) {
      // If the rule being edited is being deleted, reset the editing rule
      setEditingRule(null);
    }
  };

  return (
    <div className="rounded-md border bg-background p-4">
      <div className="flex flex-col gap-2">
        <div className="flex items-center justify-between">
          <span className="flex items-center gap-2 text-lg font-medium">
            {t("settings.rules.rules")}
            <Tooltip>
              <TooltipTrigger className="text-muted-foreground">
                <FlaskConical size={15} />
              </TooltipTrigger>
              <TooltipContent side="bottom">
                {t("common.experimental")}
              </TooltipContent>
            </Tooltip>
          </span>
          <Button onClick={handleCreateRule} variant="default">
            <PlusCircle className="mr-2 h-4 w-4" />
            {t("settings.rules.ceate_rule")}
          </Button>
        </div>
        <p className="text-sm italic text-muted-foreground">
          {t("settings.rules.description")}
        </p>
        {!rules || isLoading ? (
          <FullPageSpinner />
        ) : (
          <RuleList
            rules={rules.rules}
            onEditRule={(r) => setEditingRule(r)}
            onDeleteRule={handleDeleteRule}
          />
        )}
        <div className="lg:col-span-7">
          {editingRule && (
            <RuleEditor
              rule={editingRule}
              onCancel={() => setEditingRule(null)}
            />
          )}
        </div>
      </div>
    </div>
  );
}