Convert backend/web from submodule to regular directory

This commit is contained in:
2026-08-08 23:26:14 +02:00
parent 102a316d42
commit 0010c92103
89 changed files with 6559 additions and 1 deletions
@@ -0,0 +1,7 @@
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
@@ -0,0 +1,3 @@
export function load() {
return { title: 'Conversation' };
}
@@ -0,0 +1,80 @@
<script lang="ts">
import type { LayoutProps } from './$types';
import { page } from '$app/state';
import {uiState} from "$lib/state/ui.svelte"
import { auth } from '$lib/state/auth.svelte'
import Sidebar from "$lib/components/Sidebar.svelte"
import { goto } from '$app/navigation'
import { onMount } from "svelte";
import { applyTheme, themeToLocalStorage } from '$lib/ui/themeswitcher';
let { data, children }: LayoutProps = $props();
const handleMenuDesktop = () => {
uiState.sidebarDesktopOpen = !uiState.sidebarDesktopOpen
if (uiState.sidebarDesktopOpen) {
setTimeout(() => { uiState.menuContentVisible = uiState.sidebarDesktopOpen }, 200)
} else {
uiState.menuContentVisible = uiState.sidebarDesktopOpen
}
}
const handleMenuMobile = () => {
uiState.sidebarMobileOpen = !uiState.sidebarMobileOpen
if (uiState.sidebarMobileOpen) {
setTimeout(() => { uiState.menuContentVisible = uiState.sidebarMobileOpen }, 200)
} else {
uiState.menuContentVisible = uiState.sidebarMobileOpen
}
}
const handleResize = () => {
if (window.innerWidth < 640) {
uiState.menuContentVisible = uiState.sidebarMobileOpen
} else {
uiState.menuContentVisible = uiState.sidebarDesktopOpen
}
}
onMount(async () => {
handleResize()
if (data.me) {
auth.user = data.me
themeToLocalStorage(auth.user.theme)
applyTheme()
auth.status = 'authenticated'
} else {
auth.status = 'unauthenticated'
}
})
$effect(() => {
if (auth.status == 'unauthenticated') {
goto("/login")
}
});
</script>
<svelte:window onresize={handleResize} />
<div id="outer" class={[uiState.sidebarDesktopOpen ? "desktopMenuOpen" : "desktopMenuClosed", uiState.sidebarMobileOpen ? "mobileMenuOpen" : "mobileMenuClosed" ]}>
<div id="sidebar" class="flex flex-col">
<Sidebar {handleMenuDesktop} {handleMenuMobile}/>
</div>
<div id="main">
<div class="flex flex-col h-screen ">
<div class={["header", page.data.theme]}>
<h1 class="flex">
<span class="flex-1">{page.data.title}</span>
{#if page.data.back}
<span><a href={page.data.back} title="retour"><i class="icon-left-big"></i></a></span>
{/if}
</h1>
</div>
<div class="overflow-scroll flex-1 p-2">
{@render children()}
</div>
</div>
</div>
</div>
@@ -0,0 +1,8 @@
import { userApi } from "$lib/api/endpoints/user"
import type { LayoutLoad } from './$types';
export const load: LayoutLoad = async () => {
return {
me: await userApi.me()
}
}
@@ -0,0 +1,6 @@
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
@@ -0,0 +1,3 @@
export function load() {
return { title: 'Historique' };
}
@@ -0,0 +1,3 @@
export function load() {
return { title: 'Base de connaissance' };
}
@@ -0,0 +1,109 @@
<script lang="ts">
import { SvelteMap } from 'svelte/reactivity';
import type { PageProps } from './$types';
import { type User } from '$lib/types/api'
import { userApi } from '$lib/api/endpoints/user'
import FormError from '$lib/components/FormError.svelte';
import { applyTheme, themeToLocalStorage } from '$lib/ui/themeswitcher';
import { validateEmail } from '$lib/utilities/validators'
let { data }: PageProps = $props();
let form : User = $state(data.me)
let errors = new SvelteMap<string,string>()
$effect(()=>{
themeToLocalStorage(form.theme)
applyTheme()
})
let submitUser = (e: Event) => {
e.preventDefault()
if (!validateEmail(form.email)) {
errors.set("email","Adresse email invalide !")
}
if (!form.firstname) {
errors.set("firstname","Le prénom est obligatoire !")
}
if (!form.lastname) {
errors.set("lastname","Le nom est obligatoire !")
}
if (errors.size==0) {
userApi.update(form.id, form)
.then(()=>{ console.log('success')})
.catch((err: string)=>{ console.error(err)})
}
}
</script>
<div class="mb-4 formgroup">
<h2>Mon compte</h2>
<form onsubmit={submitUser} onchange={()=>{errors.clear()}}>
<label for="email" class="block my-1 flex-1">Email</label>
<input
id="email"
type="text"
bind:value={form.email}
class="textinput"
autofocus
/>
<FormError key="email" errors={errors} />
<div class="flex">
<div class="flex-1 mr-2">
<label for="firstname" class="block my-1 flex-1">Prénom</label>
<input
id="firstname"
type="text"
bind:value={form.firstname}
class="textinput"
/>
<FormError key="firstname" errors={errors} />
</div>
<div class="flex-1 ml-2">
<label for="lastname" class="block my-1 flex-1">Nom</label>
<input
id="lastname"
type="text"
bind:value={form.lastname}
class="textinput"
/>
<FormError key="lastname" errors={errors} />
</div>
</div>
<div class="flex">
<div class="flex-1 mr-2">
<label for="theme" class="block my-1 flex-1">Thème</label>
<select bind:value={form.theme} class="textinput">
<option value="auto">Automatic</option>
<option value="dark">Sombre</option>
<option value="light">Clair</option>
</select>
<FormError key="theme" errors={errors} />
</div>
<div class="flex-1 ml-2">
<label for="lang" class="block my-1 flex-1">Langue</label>
<select bind:value={form.lang} class="textinput">
<option value="en">English</option>
<option value="fr">Français</option>
</select>
<FormError key="lang" errors={errors} />
</div>
</div>
<button class="bt w-full">Enregistrer</button>
</form>
</div>
<div class="mb-4 formgroup">
<h2>Canaux de communication</h2>
</div>
@@ -0,0 +1,9 @@
import { userApi } from "$lib/api/endpoints/user"
import type { PageLoad } from './$types';
export const load: PageLoad = async () => {
return {
title: 'Profil',
me: await userApi.me()
}
}
@@ -0,0 +1,58 @@
<div class="grid grid-cols-[repeat(auto-fit,minmax(250px,1fr))] gap-4">
<a class="bt p-5 text-center"
title="Modèles"
href="/settings/models">
Modèles
<span class="ml-2 opacity-50 text-xs">mistral-medium-latest</span>
</a>
<a class="bt p-5 text-center"
title="Outils"
href="/settings/tools"
>
Outils
<span class="ml-2 text-xs bg-red-900 text-red-300 rounded-lg p-1">12</span>
</a>
<a class="bt p-5 text-center"
title="Skills"
href="/settings/skills">
Skills
<span class="ml-2 text-xs bg-red-900 text-red-300 rounded-lg p-1">3</span>
</a>
<a class="bt p-5 text-center"
title="Canaux de communication"
href="/settings/channels"
>
Canaux de communication
<span class="ml-2 text-xs bg-red-900 text-red-300 rounded-lg p-1">12</span>
</a>
<a class="bt p-5 text-center"
title="Bases de connaissance"
href="/settings/kb">
Bases de connaissance
</a>
<a class="bt p-5 text-center"
title="Agents"
href="/settings/agents">
Agents
</a>
<a class="bt p-5 text-center"
title="Mémoire"
href="/settings/memory">
Mémoire
<span class="ml-2 opacity-50 text-xs">standard</span>
</a>
<a class="bt p-5 text-center"
title="Utilisateurs"
href="/settings/users">
Utilisateurs
<span class="ml-2 text-xs bg-red-900 text-red-300 rounded-lg p-1">1</span>
</a>
</div>
@@ -0,0 +1,3 @@
export function load() {
return { title: 'Paramétrage', theme: "settings" };
}
@@ -0,0 +1 @@
<div>Modèles</div>
@@ -0,0 +1,7 @@
export function load() {
return {
title: 'Paramétrage : Agents',
back: "/settings",
theme: "settings"
};
}
@@ -0,0 +1 @@
<div>Modèles</div>
@@ -0,0 +1,7 @@
export function load() {
return {
title: 'Paramétrage : Canaux de communication',
back: "/settings",
theme: "settings"
};
}
@@ -0,0 +1 @@
<div>Modèles</div>
@@ -0,0 +1,7 @@
export function load() {
return {
title: 'Paramétrage : Base de connaissance',
back: "/settings",
theme: "settings"
};
}
@@ -0,0 +1 @@
<div>Modèles</div>
@@ -0,0 +1,7 @@
export function load() {
return {
title: 'Paramétrage : Mémoire',
back: "/settings",
theme: "settings"
};
}
@@ -0,0 +1 @@
<div>Modèles</div>
@@ -0,0 +1,7 @@
export function load() {
return {
title: 'Paramétrage : Modèles',
back: "/settings",
theme: "settings"
};
}
@@ -0,0 +1 @@
<div>Modèles</div>
@@ -0,0 +1,7 @@
export function load() {
return {
title: 'Paramétrage : Skills',
back: "/settings",
theme: "settings"
};
}
@@ -0,0 +1 @@
<div>Modèles</div>
@@ -0,0 +1,7 @@
export function load() {
return {
title: 'Paramétrage : Outils',
back: "/settings",
theme: "settings"
};
}
@@ -0,0 +1 @@
<div>Modèles</div>
@@ -0,0 +1,7 @@
export function load() {
return {
title: 'Paramétrage : Utilisateurs',
back: "/settings",
theme: "settings"
};
}
@@ -0,0 +1,3 @@
<div>
Tâches
</div>
@@ -0,0 +1,3 @@
export function load() {
return { title: 'Tâches' };
}