rename rules (#26)

This commit is contained in:
Aidan Bleser 2025-06-18 17:38:33 -05:00 committed by GitHub
parent 0629c5abd4
commit 625cca98c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 74 additions and 3 deletions

View file

@ -101,3 +101,34 @@ export const all = query({
return allRules;
},
});
export const rename = mutation({
args: {
ruleId: v.id('user_rules'),
name: v.string(),
session_token: v.string(),
},
handler: async (ctx, args) => {
const session = await ctx.runQuery(internal.betterAuth.getSession, {
sessionToken: args.session_token,
});
if (!session) throw new Error('Invalid session token');
const existing = await ctx.db.get(args.ruleId);
if (!existing) throw new Error('Rule not found');
if (existing.user_id !== session.userId) throw new Error('You are not the owner of this rule');
const existingWithName = await ctx.db
.query('user_rules')
.withIndex('by_user_name', (q) => q.eq('user_id', session.userId).eq('name', args.name))
.first();
if (existingWithName) throw new Error('Rule with this name already exists');
await ctx.db.patch(args.ruleId, {
name: args.name,
});
},
});

View file

@ -124,6 +124,6 @@
</div>
{/if}
{#each userRulesQuery.data ?? [] as rule (rule._id)}
<Rule {rule} />
<Rule {rule} allRules={userRulesQuery.data ?? []} />
{/each}
</div>

View file

@ -11,14 +11,16 @@
import { ResultAsync } from 'neverthrow';
import TrashIcon from '~icons/lucide/trash';
import { callModal } from '$lib/components/ui/modal/global-modal.svelte';
import { Input } from '$lib/components/ui/input';
type Props = {
rule: Doc<'user_rules'>;
allRules: Doc<'user_rules'>[];
};
const id = $props.id();
let { rule }: Props = $props();
let { rule, allRules }: Props = $props();
const client = useConvexClient();
@ -76,14 +78,52 @@
deleting = false;
}
let ruleName = $derived(rule.name);
let renaming = $state(false);
async function renameRule() {
renaming = true;
await ResultAsync.fromPromise(
client.mutation(api.user_rules.rename, {
ruleId: rule._id,
name: ruleName,
session_token: session.current?.session.token ?? '',
}),
(e) => e
);
renaming = false;
}
const ruleNameExists = $derived.by(() => {
for (const r of allRules) {
if (r._id === rule._id) continue;
if (r.name === ruleName) return true;
}
return false;
});
</script>
<Card.Root>
<Card.Header>
<div class="flex items-center justify-between">
<Card.Title>{rule.name}</Card.Title>
<div class="flex items-center gap-2">
<Input bind:value={ruleName} aria-invalid={ruleNameExists} />
<Button
variant="outline"
onClickPromise={renameRule}
disabled={ruleNameExists || ruleName === rule.name}
>
Rename
</Button>
</div>
<Button variant="destructive" size="icon" onclick={deleteRule} disabled={deleting}>
<TrashIcon class="size-4" />
<span class="sr-only">Delete Rule</span>
</Button>
</div>
</Card.Header>