feat: skills frontend

This commit is contained in:
Timothy Jaeryang Baek committed 2026-02-11 14:22:26 -06:00
1 parent a38ad8fc42
commit 1973115678
9 files changed
+1198

No files matched your search

+11
View File
@@ -121,6 +121,17 @@
{$i18n.t('Tools')}
</a>
{/if}
{#if $user?.role === 'admin' || $user?.permissions?.workspace?.skills}
<a
class="min-w-fit p-1.5 {$page.url.pathname.includes('/workspace/skills')
? ''
: 'text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
href="/workspace/skills"
>
{$i18n.t('Skills')}
</a>
{/if}
</div>
</div>
@@ -0,0 +1,5 @@
<script>
import Skills from '$lib/components/workspace/Skills.svelte';
</script>
<Skills />
@@ -0,0 +1,56 @@
<script lang="ts">
import { toast } from 'svelte-sonner';
import { goto } from '$app/navigation';
import { skills } from '$lib/stores';
import { onMount, getContext } from 'svelte';
const i18n = getContext('i18n');
import { createNewSkill, getSkills } from '$lib/apis/skills';
import SkillEditor from '$lib/components/workspace/Skills/SkillEditor.svelte';
let skill: {
name: string;
id: string;
description: string;
content: string;
is_active: boolean;
access_grants: any[];
} | null = null;
let clone = false;
const onSubmit = async (_skill) => {
const res = await createNewSkill(localStorage.token, _skill).catch((error) => {
toast.error(`${error}`);
return null;
});
if (res) {
toast.success($i18n.t('Skill created successfully'));
await skills.set(await getSkills(localStorage.token));
await goto('/workspace/skills');
}
};
onMount(async () => {
if (sessionStorage.skill) {
const _skill = JSON.parse(sessionStorage.skill);
sessionStorage.removeItem('skill');
clone = true;
skill = {
name: _skill.name || 'Skill',
id: _skill.id || '',
description: _skill.description || '',
content: _skill.content || '',
is_active: _skill.is_active ?? true,
access_grants: _skill.access_grants !== undefined ? _skill.access_grants : []
};
}
});
</script>
{#key skill}
<SkillEditor {skill} {onSubmit} {clone} />
{/key}
@@ -0,0 +1,71 @@
<script lang="ts">
import { toast } from 'svelte-sonner';
import { goto } from '$app/navigation';
import { skills } from '$lib/stores';
import { onMount, getContext } from 'svelte';
const i18n = getContext('i18n');
import { getSkillById, getSkills, updateSkillById } from '$lib/apis/skills';
import { page } from '$app/stores';
import SkillEditor from '$lib/components/workspace/Skills/SkillEditor.svelte';
let skill = null;
let disabled = false;
$: skillId = $page.url.searchParams.get('id');
const onSubmit = async (_skill) => {
const updatedSkill = await updateSkillById(localStorage.token, skillId, _skill).catch(
(error) => {
toast.error(`${error}`);
return null;
}
);
if (updatedSkill) {
toast.success($i18n.t('Skill updated successfully'));
await skills.set(await getSkills(localStorage.token));
skill = {
id: updatedSkill.id,
name: updatedSkill.name,
description: updatedSkill.description,
content: updatedSkill.content,
is_active: updatedSkill.is_active,
access_grants:
updatedSkill?.access_grants === undefined ? [] : updatedSkill?.access_grants
};
}
};
onMount(async () => {
if (skillId) {
const _skill = await getSkillById(localStorage.token, skillId).catch((error) => {
toast.error(`${error}`);
return null;
});
if (_skill) {
disabled = !_skill.write_access ?? true;
skill = {
id: _skill.id,
name: _skill.name,
description: _skill.description,
content: _skill.content,
is_active: _skill.is_active,
access_grants:
_skill?.access_grants === undefined ? [] : _skill?.access_grants
};
} else {
goto('/workspace/skills');
}
} else {
goto('/workspace/skills');
}
});
</script>
{#if skill}
<SkillEditor {skill} {onSubmit} {disabled} edit />
{/if}