Compare commits

...

6 commits

16 changed files with 88 additions and 28 deletions

View file

@ -5,6 +5,8 @@ import de.hhhammer.dchat.db.UserDBService;
import de.hhhammer.dchat.web.server.ConfigCrudHandler; import de.hhhammer.dchat.web.server.ConfigCrudHandler;
import de.hhhammer.dchat.web.user.ConfigUserCrudHandler; import de.hhhammer.dchat.web.user.ConfigUserCrudHandler;
import io.javalin.Javalin; import io.javalin.Javalin;
import io.javalin.http.HandlerType;
import io.javalin.http.HttpStatus;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -41,7 +43,9 @@ public class WebAPI implements Runnable {
}); });
app.before(ctx -> { app.before(ctx -> {
ctx.header("Access-Control-Allow-Origin", "*"); ctx.header("Access-Control-Allow-Origin", "*");
ctx.header("Access-Control-Allow-Methods", "*");
}); });
app.options("*", ctx -> ctx.status(HttpStatus.OK));
app.get("/", ctx -> ctx.result(""" app.get("/", ctx -> ctx.result("""
{ "message": "Hello World"} { "message": "Hello World"}

View file

@ -1,5 +1,6 @@
package de.hhhammer.dchat.db.models.server; package de.hhhammer.dchat.db.models.server;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import de.hhhammer.dchat.db.ResultSetTransformer; import de.hhhammer.dchat.db.ResultSetTransformer;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -22,6 +23,7 @@ public record ServerConfig(long id, long serverId, String systemMessage, int rat
} }
} }
@JsonIgnoreProperties(ignoreUnknown = true)
public record NewServerConfig(long serverId, String systemMessage, @Nullable int rateLimit) { public record NewServerConfig(long serverId, String systemMessage, @Nullable int rateLimit) {
} }
} }

View file

@ -1,5 +1,6 @@
package de.hhhammer.dchat.db.models.server; package de.hhhammer.dchat.db.models.server;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import de.hhhammer.dchat.db.ResultSetTransformer; import de.hhhammer.dchat.db.ResultSetTransformer;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -21,6 +22,7 @@ public record ServerMessage(long id, long serverId, long userId, int tokens, Ins
} }
} }
@JsonIgnoreProperties(ignoreUnknown = true)
public record NewServerMessage(long serverId, long userId, int tokens) { public record NewServerMessage(long serverId, long userId, int tokens) {
} }
} }

View file

@ -1,5 +1,6 @@
package de.hhhammer.dchat.db.models.user; package de.hhhammer.dchat.db.models.user;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import de.hhhammer.dchat.db.ResultSetTransformer; import de.hhhammer.dchat.db.ResultSetTransformer;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -23,6 +24,7 @@ public record UserConfig(long id, long userId, String systemMessage, int context
} }
} }
@JsonIgnoreProperties(ignoreUnknown = true)
public record NewUserConfig(long userId, String systemMessage, @Nullable int contextLength, public record NewUserConfig(long userId, String systemMessage, @Nullable int contextLength,
@Nullable int rateLimit) { @Nullable int rateLimit) {
} }

View file

@ -1,5 +1,6 @@
package de.hhhammer.dchat.db.models.user; package de.hhhammer.dchat.db.models.user;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import de.hhhammer.dchat.db.ResultSetTransformer; import de.hhhammer.dchat.db.ResultSetTransformer;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -22,6 +23,7 @@ public record UserMessage(long id, long userId, String question, String answer,
} }
} }
@JsonIgnoreProperties(ignoreUnknown = true)
public record NewUserMessage(long userId, String question, String answer, int tokens) { public record NewUserMessage(long userId, String question, String answer, int tokens) {
} }
} }

View file

@ -21,15 +21,13 @@ const { tableHeader, tableRows, showActions } = defineProps<{
</thead> </thead>
<tbody> <tbody>
<!-- row --> <!-- row -->
<tr> <tr v-for="row in tableRows">
<template v-for="row in tableRows">
<template v-for="data in row"> <template v-for="data in row">
<th>{{ data }}</th> <th>{{ data }}</th>
</template> </template>
<th> <th>
<slot name="action" :row="row"/> <slot name="action" :row="row" />
</th> </th>
</template>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View file

@ -1,13 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import ModalComponent from '@/components/ModalComponent.vue'; import ModalComponent from '@/components/ModalComponent.vue';
import type { ServerConfig } from "@/models/server"; import type { ServerConfig } from "@/models/server";
import { addConfig } from '@/services/ServerConfigs';
import { ref } from 'vue' import { ref } from 'vue'
const modalId = "addServerConfig" const modalId = "addServerConfig"
const newConfig = ref<ServerConfig | Record<string, never>>({}) const newConfig = ref<ServerConfig | Record<string, never>>({})
const submitAction = async () => { const submitAction = async () => {
console.log("Saving: ", newConfig.value) if (!newConfig) {
return
}
return addConfig(newConfig.value as ServerConfig)
} }
</script> </script>
<template> <template>

View file

@ -1,12 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import ModalComponent from '@/components/ModalComponent.vue'; import ModalComponent from '@/components/ModalComponent.vue';
import type { ServerConfig } from "@/models/server"; import { deleteConfig } from '@/services/ServerConfigs';
import { ref } from 'vue'
const { id } = defineProps<{ id: number }>() const { id } = defineProps<{ id: number }>()
const submitAction = async () => { const submitAction = async () => {
console.log("deleting: ", id) return deleteConfig(id)
} }
const modalId = "delete-" + id const modalId = "delete-" + id
</script> </script>

View file

@ -3,13 +3,13 @@ import ModalComponent from '@/components/ModalComponent.vue';
import { getConfig } from '@/services/ServerConfigs' import { getConfig } from '@/services/ServerConfigs'
import { ref } from 'vue'; import { ref } from 'vue';
import type { ServerConfig } from '@/models/server'; import type { ServerConfig } from '@/models/server';
import { updateConfig } from '@/services/ServerConfigs';
const { id } = defineProps<{ id: number }>() const { id } = defineProps<{ id: number }>()
const configToEdit = ref<ServerConfig | Record<string, never>>({}) const configToEdit = ref<ServerConfig | Record<string, never>>({})
const submitAction = async () => { const submitAction = async () => {
console.log(id) return updateConfig(id, configToEdit.value as ServerConfig)
console.log("Saving: ", configToEdit.value)
} }
const onLoadAction = async () => { const onLoadAction = async () => {

View file

@ -2,12 +2,13 @@
import ModalComponent from '@/components/ModalComponent.vue'; import ModalComponent from '@/components/ModalComponent.vue';
import type { UserConfig } from "@/models/user"; import type { UserConfig } from "@/models/user";
import { ref } from 'vue' import { ref } from 'vue'
import { addConfig } from '@/services/UserConfigs';
const modalId = "addUserConfig" const modalId = "addUserConfig"
const newConfig = ref<UserConfig | Record<string, never>>({}) const newConfig = ref<UserConfig | Record<string, never>>({})
const submitAction = async () => { const submitAction = async () => {
console.log("Saving: ", newConfig.value) return addConfig(newConfig.value as UserConfig)
} }
</script> </script>
<template> <template>

View file

@ -1,12 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import ModalComponent from '@/components/ModalComponent.vue'; import ModalComponent from '@/components/ModalComponent.vue';
import type { ServerConfig } from "@/models/server"; import { deleteConfig } from '@/services/UserConfigs';
import { ref } from 'vue'
const { id } = defineProps<{ id: number }>() const { id } = defineProps<{ id: number }>()
const submitAction = async () => { const submitAction = async () => {
console.log("deleting: ", id) return deleteConfig(id)
} }
const modalId = "delete-" + id const modalId = "delete-" + id
</script> </script>

View file

@ -3,14 +3,13 @@ import ModalComponent from '@/components/ModalComponent.vue';
import { getConfig } from '@/services/UserConfigs' import { getConfig } from '@/services/UserConfigs'
import { ref } from 'vue'; import { ref } from 'vue';
import type { UserConfig } from '@/models/user'; import type { UserConfig } from '@/models/user';
import { updateConfig } from '@/services/UserConfigs';
const { id } = defineProps<{ id: number }>() const { id } = defineProps<{ id: number }>()
const configToEdit = ref<UserConfig | Record<string, never>>({}) const configToEdit = ref<UserConfig | Record<string, never>>({})
const submitAction = async () => { const submitAction = async () => {
console.log(id) return updateConfig(id, configToEdit.value as UserConfig)
console.log("Saving: ", configToEdit.value)
} }
const onLoadAction = async () => { const onLoadAction = async () => {
configToEdit.value = await getConfig(id) configToEdit.value = await getConfig(id)

View file

@ -1,17 +1,38 @@
import type { ServerConfig } from "@/models/server"; import type { ServerConfig } from "@/models/server";
const configUrl = import.meta.env.VITE_API_URL + "/servers/configs/"
export async function getConfigs(): Promise<ServerConfig[]> { export async function getConfigs(): Promise<ServerConfig[]> {
return fetch(import.meta.env.VITE_API_URL + "/servers/configs") return fetch(configUrl)
.then(shouldBeSuccess) .then(shouldBeSuccess)
.then(res => res.json()) .then(res => res.json())
} }
export function getConfig(id: number): Promise<ServerConfig> { export function getConfig(id: number): Promise<ServerConfig> {
return fetch(import.meta.env.VITE_API_URL + "/servers/configs/" + id) return fetch(configUrl + id)
.then(shouldBeSuccess) .then(shouldBeSuccess)
.then(res => res.json()) .then(res => res.json())
} }
export function updateConfig(id: number, config: ServerConfig): Promise<void> {
return fetch(configUrl + id, { method: "PATCH", body: JSON.stringify(config) })
.then(shouldBeSuccess)
.then()
}
export function addConfig(config: ServerConfig): Promise<void> {
debugger
return fetch(configUrl, { method: "POST", body: JSON.stringify(config) })
.then(shouldBeSuccess)
.then()
}
export function deleteConfig(id: number): Promise<void> {
return fetch(configUrl + id, { method: "DELETE" })
.then(shouldBeSuccess)
.then()
}
function shouldBeSuccess(res: Response): Response { function shouldBeSuccess(res: Response): Response {
if (res.status >= 200 && res.status < 300) return res if (res.status >= 200 && res.status < 300) return res
throw new Error(`Expected success status code but got: ${res.status} ${res.statusText}`) throw new Error(`Expected success status code but got: ${res.status} ${res.statusText}`)

View file

@ -1,17 +1,39 @@
import type {UserConfig} from '@/models/user' import type { UserConfig } from '@/models/user'
const configUrl = import.meta.env.VITE_API_URL + "/users/configs/"
export async function getConfigs(): Promise<UserConfig[]> { export async function getConfigs(): Promise<UserConfig[]> {
return fetch(import.meta.env.VITE_API_URL + "/users/configs") return fetch(configUrl)
.then(shouldBeSuccess) .then(shouldBeSuccess)
.then(res => res.json()) .then(res => res.json())
} }
export function getConfig(id: number): Promise<UserConfig> { export function getConfig(id: number): Promise<UserConfig> {
return fetch(import.meta.env.VITE_API_URL + "/users/configs/" + id) return fetch(configUrl + id)
.then(shouldBeSuccess) .then(shouldBeSuccess)
.then(res => res.json()) .then(res => res.json())
} }
export function updateConfig(id: number, config: UserConfig): Promise<void> {
return fetch(configUrl + id, { method: "PATCH", body: JSON.stringify(config) })
.then(shouldBeSuccess)
.then()
}
export function addConfig(config: UserConfig): Promise<void> {
debugger
return fetch(configUrl, { method: "POST", body: JSON.stringify(config) })
.then(shouldBeSuccess)
.then()
}
export function deleteConfig(id: number): Promise<void> {
return fetch(configUrl + id, { method: "DELETE" })
.then(shouldBeSuccess)
.then()
}
function shouldBeSuccess(res: Response): Response { function shouldBeSuccess(res: Response): Response {
if (res.status >= 200 && res.status < 300) return res if (res.status >= 200 && res.status < 300) return res
throw new Error(`Expected success status code but got: ${res.status} ${res.statusText}`) throw new Error(`Expected success status code but got: ${res.status} ${res.statusText}`)

View file

@ -5,9 +5,12 @@ import { getConfigs } from '@/services/ServerConfigs'
import EditServerConfig from '@/components/server/EditServerConfig.vue'; import EditServerConfig from '@/components/server/EditServerConfig.vue';
import DeleteServerConfig from '@/components/server/DeleteServerConfig.vue'; import DeleteServerConfig from '@/components/server/DeleteServerConfig.vue';
const trimSystemMessage = (str: string) => str.length > 50 ? str.slice(0, 47) + "..." : str
const serverConfigs = await getConfigs() const serverConfigs = await getConfigs()
const tableHeader = ["ID", "Server ID", "System Message", "Rate limit", "Created"] const tableHeader = ["ID", "Server ID", "System Message", "Rate limit", "Created"]
const tableRows = serverConfigs.map(config => [config.id, config.serverId, config.systemMessage.slice(0, 47) + "...", config.rateLimit, config.time]) const tableRows = serverConfigs.map(config => [config.id, config.serverId, trimSystemMessage(config.systemMessage), config.rateLimit, config.time])
</script> </script>
<template> <template>
<div class="flex justify-between m-5"> <div class="flex justify-between m-5">

View file

@ -5,10 +5,12 @@ import { getConfigs } from '@/services/UserConfigs'
import EditUserConfig from '@/components/user/EditUserConfig.vue'; import EditUserConfig from '@/components/user/EditUserConfig.vue';
import DeleteServerConfig from '@/components/server/DeleteServerConfig.vue'; import DeleteServerConfig from '@/components/server/DeleteServerConfig.vue';
const trimSystemMessage = (str: string) => str.length > 50 ? str.slice(0, 47) + "..." : str
const userConfigs = await getConfigs() const userConfigs = await getConfigs()
const tableHeader = ["ID", "User ID", "System Message", "Context Length", "Rate limit", "Created"] const tableHeader = ["ID", "User ID", "System Message", "Context Length", "Rate limit", "Created"]
const tableRows = userConfigs.map(config => [config.id, config.userId, config.systemMessage.slice(0, 47) + "...", config.contextLength, config.rateLimit, config.time]) const tableRows = userConfigs.map(config => [config.id, config.userId, trimSystemMessage(config.systemMessage), config.contextLength, config.rateLimit, config.time])
</script> </script>
<template> <template>
<div class="flex justify-between m-5"> <div class="flex justify-between m-5">