rename rules (#26)
This commit is contained in:
parent
0629c5abd4
commit
625cca98c5
3 changed files with 74 additions and 3 deletions
|
|
@ -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,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
@ -124,6 +124,6 @@
|
|||
</div>
|
||||
{/if}
|
||||
{#each userRulesQuery.data ?? [] as rule (rule._id)}
|
||||
<Rule {rule} />
|
||||
<Rule {rule} allRules={userRulesQuery.data ?? []} />
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue