swap to fly.io
This commit is contained in:
parent
a5a322cd38
commit
f2f6547b22
@ -1 +1 @@
|
|||||||
data/
|
data
|
38
Chat.go
38
Chat.go
@ -398,8 +398,8 @@ func generateLimitReachedChatHTML() string {
|
|||||||
// TODO Replace by live API call
|
// TODO Replace by live API call
|
||||||
stripeTable := `
|
stripeTable := `
|
||||||
<stripe-pricing-table
|
<stripe-pricing-table
|
||||||
pricing-table-id="prctbl_1OxrazP2nW0okNQymYvskUk7"
|
pricing-table-id="prctbl_1PJAxDP2nW0okNQyY0Q3mbg4"
|
||||||
publishable-key="pk_test_51OxXuWP2nW0okNQy2jyS70vx7WHZzDskvQazsitSDJQ3ifVHPqAkMv7orCePwRGRTarNn8uMuaxbVqD2Zg80oRc600epN4ycQ4"
|
publishable-key="pk_live_51OxXuWP2nW0okNQyme1qdwbL535jbMmM1uIUi6U5zcvEUUwKraktmpCzudXNdPSTxlHpw2FbCtxpwbyFFcasQ7aj000tJJGpWW"
|
||||||
customer-session-client-secret="` + clientSecretSession + `">
|
customer-session-client-secret="` + clientSecretSession + `">
|
||||||
</stripe-pricing-table>`
|
</stripe-pricing-table>`
|
||||||
|
|
||||||
@ -449,8 +449,7 @@ func GetEditMessageFormHandler(c *fiber.Ctx) error {
|
|||||||
rows = 10
|
rows = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl := pongo2.Must(pongo2.FromFile("views/partials/message-edit-form.html"))
|
out, err := messageEditTmpl.Execute(pongo2.Context{"Content": message.Content, "ID": id, "Rows": rows})
|
||||||
out, err := tmpl.Execute(pongo2.Context{"Content": message.Content, "ID": id, "Rows": rows})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error executing user template")
|
fmt.Println("Error executing user template")
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -608,7 +607,7 @@ func LoadUsageKPIHandler(c *fiber.Ctx) error {
|
|||||||
TotalCount += usage.TotalCount
|
TotalCount += usage.TotalCount
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-usage.html")).Execute(pongo2.Context{
|
out, err := usagePopoverTmpl.Execute(pongo2.Context{
|
||||||
"usages": usages,
|
"usages": usages,
|
||||||
"TotalCost": TotalCost,
|
"TotalCost": TotalCost,
|
||||||
"TotalCount": TotalCount,
|
"TotalCount": TotalCount,
|
||||||
@ -624,29 +623,6 @@ func LoadUsageKPIHandler(c *fiber.Ctx) error {
|
|||||||
return c.SendString(out)
|
return c.SendString(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadKeysHandler(c *fiber.Ctx) error {
|
|
||||||
if !checkIfLogin() {
|
|
||||||
return c.SendString("")
|
|
||||||
}
|
|
||||||
openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists := getExistingKeys()
|
|
||||||
|
|
||||||
out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-keys.html")).Execute(pongo2.Context{
|
|
||||||
"IsLogin": checkIfLogin(),
|
|
||||||
"OpenaiExists": openaiExists,
|
|
||||||
"AnthropicExists": anthropicExists,
|
|
||||||
"MistralExists": mistralExists,
|
|
||||||
"GroqExists": groqExists,
|
|
||||||
"GooseaiExists": gooseaiExists,
|
|
||||||
"GoogleExists": googleExists,
|
|
||||||
"AnyExists": openaiExists || anthropicExists || mistralExists || groqExists || gooseaiExists || googleExists,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error loading keys")
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return c.SendString(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenerateModelPopoverHTML(refresh bool) string {
|
func GenerateModelPopoverHTML(refresh bool) string {
|
||||||
openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists := getExistingKeys()
|
openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists := getExistingKeys()
|
||||||
|
|
||||||
@ -676,7 +652,7 @@ func GenerateModelPopoverHTML(refresh bool) string {
|
|||||||
|
|
||||||
modelInfos := GetAvailableModels()
|
modelInfos := GetAvailableModels()
|
||||||
|
|
||||||
out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-models.html")).Execute(pongo2.Context{
|
out, err := modelPopoverTmpl.Execute(pongo2.Context{
|
||||||
"IsLogin": checkIfLogin(),
|
"IsLogin": checkIfLogin(),
|
||||||
"OpenaiExists": openaiExists,
|
"OpenaiExists": openaiExists,
|
||||||
"AnthropicExists": anthropicExists,
|
"AnthropicExists": anthropicExists,
|
||||||
@ -720,7 +696,7 @@ func GenerateConversationPopoverHTML(isActive bool) string {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-conversation.html")).Execute(pongo2.Context{
|
out, err := conversationPopoverTmpl.Execute(pongo2.Context{
|
||||||
"Conversations": conversations,
|
"Conversations": conversations,
|
||||||
"IsActive": isActive,
|
"IsActive": isActive,
|
||||||
})
|
})
|
||||||
@ -768,7 +744,7 @@ func LoadSettingsHandler(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists := getExistingKeys()
|
openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists := getExistingKeys()
|
||||||
|
|
||||||
out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-settings.html")).Execute(pongo2.Context{
|
out, err := settingPopoverTmpl.Execute(pongo2.Context{
|
||||||
"IsLogin": checkIfLogin(),
|
"IsLogin": checkIfLogin(),
|
||||||
"OpenaiExists": openaiExists,
|
"OpenaiExists": openaiExists,
|
||||||
"AnthropicExists": anthropicExists,
|
"AnthropicExists": anthropicExists,
|
||||||
|
@ -72,11 +72,13 @@ func TestMistralKey(apiKey string) bool {
|
|||||||
|
|
||||||
jsonBody, err := json.Marshal(requestBody)
|
jsonBody, err := json.Marshal(requestBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("Error marshalling request to Mistral")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody))
|
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("Error creating request to Mistral")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,21 +89,25 @@ func TestMistralKey(apiKey string) bool {
|
|||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("Error sending request to Mistral")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("Error reading response from Mistral")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var chatCompletionResponse MistralChatCompletionResponse
|
var chatCompletionResponse MistralChatCompletionResponse
|
||||||
err = json.Unmarshal(body, &chatCompletionResponse)
|
err = json.Unmarshal(body, &chatCompletionResponse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("Error unmarshalling response from Mistral")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if chatCompletionResponse.Usage.CompletionTokens == 0 {
|
if chatCompletionResponse.Usage.CompletionTokens == 0 {
|
||||||
|
fmt.Println("No response from Mistral")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -31,8 +31,8 @@ func generatePricingTableChatHTML() string {
|
|||||||
// TODO Replace by live API call
|
// TODO Replace by live API call
|
||||||
stripeTable := `
|
stripeTable := `
|
||||||
<stripe-pricing-table
|
<stripe-pricing-table
|
||||||
pricing-table-id="prctbl_1OxrazP2nW0okNQymYvskUk7"
|
pricing-table-id="prctbl_1PJAxDP2nW0okNQyY0Q3mbg4"
|
||||||
publishable-key="pk_test_51OxXuWP2nW0okNQy2jyS70vx7WHZzDskvQazsitSDJQ3ifVHPqAkMv7orCePwRGRTarNn8uMuaxbVqD2Zg80oRc600epN4ycQ4"
|
publishable-key="pk_live_51OxXuWP2nW0okNQyme1qdwbL535jbMmM1uIUi6U5zcvEUUwKraktmpCzudXNdPSTxlHpw2FbCtxpwbyFFcasQ7aj000tJJGpWW"
|
||||||
customer-session-client-secret="` + clientSecretSession + `">
|
customer-session-client-secret="` + clientSecretSession + `">
|
||||||
</stripe-pricing-table>`
|
</stripe-pricing-table>`
|
||||||
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
|
|
||||||
docker build -t mrbounty1/jade:jadeAlpha1 .
|
|
||||||
docker push mrbounty1/jade:jadeAlpha1
|
|
@ -196,7 +196,7 @@ func insertUserMessage(content string) edgedb.UUID {
|
|||||||
conversation := global currentConversation,
|
conversation := global currentConversation,
|
||||||
selected := true,
|
selected := true,
|
||||||
llm := (
|
llm := (
|
||||||
SELECT LLM FILTER .id = <uuid>"32cb4f0c-1c3f-11ef-9247-2fac0086a7d1"
|
SELECT LLM FILTER .id = <uuid>"f777f024-1da9-11ef-afd4-bf1c8b177a62"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
`, &inserted, "user", content, lastArea.ID)
|
`, &inserted, "user", content, lastArea.ID)
|
||||||
|
21
fly.toml
Normal file
21
fly.toml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# fly.toml app configuration file generated for jade-2-0 on 2024-05-28T19:35:25+02:00
|
||||||
|
#
|
||||||
|
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
|
||||||
|
#
|
||||||
|
|
||||||
|
app = 'jade-2-0'
|
||||||
|
primary_region = 'cdg'
|
||||||
|
|
||||||
|
[build]
|
||||||
|
|
||||||
|
[http_service]
|
||||||
|
internal_port = 8080
|
||||||
|
force_https = true
|
||||||
|
auto_stop_machines = true
|
||||||
|
auto_start_machines = true
|
||||||
|
min_machines_running = 0
|
||||||
|
processes = ['app']
|
||||||
|
|
||||||
|
[[vm]]
|
||||||
|
size = 'shared-cpu-1x'
|
||||||
|
memory = "256MB"
|
41
main.go
41
main.go
@ -32,19 +32,30 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/flosch/pongo2"
|
"github.com/flosch/pongo2"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/gofiber/fiber/v2/middleware/favicon"
|
||||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||||
"github.com/gofiber/fiber/v2/middleware/recover"
|
"github.com/gofiber/fiber/v2/middleware/recover"
|
||||||
"github.com/gofiber/template/django/v3"
|
"github.com/gofiber/template/django/v3"
|
||||||
"github.com/stripe/stripe-go"
|
"github.com/stripe/stripe-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
var userTmpl *pongo2.Template
|
var (
|
||||||
var botTmpl *pongo2.Template
|
userTmpl *pongo2.Template
|
||||||
var selectBtnTmpl *pongo2.Template
|
botTmpl *pongo2.Template
|
||||||
|
selectBtnTmpl *pongo2.Template
|
||||||
|
modelPopoverTmpl *pongo2.Template
|
||||||
|
usagePopoverTmpl *pongo2.Template
|
||||||
|
settingPopoverTmpl *pongo2.Template
|
||||||
|
messageEditTmpl *pongo2.Template
|
||||||
|
conversationPopoverTmpl *pongo2.Template
|
||||||
|
clients = make(map[chan SSE]bool)
|
||||||
|
mu sync.Mutex
|
||||||
|
)
|
||||||
|
|
||||||
// SSE event structure
|
// SSE event structure
|
||||||
type SSE struct {
|
type SSE struct {
|
||||||
@ -52,12 +63,6 @@ type SSE struct {
|
|||||||
Data string
|
Data string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Global channel and mutex
|
|
||||||
var (
|
|
||||||
clients = make(map[chan SSE]bool)
|
|
||||||
mu sync.Mutex
|
|
||||||
)
|
|
||||||
|
|
||||||
// Function to send events to all clients
|
// Function to send events to all clients
|
||||||
func sendEvent(event, data string) {
|
func sendEvent(event, data string) {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
@ -69,12 +74,17 @@ func sendEvent(event, data string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// TODO Change key to env and the live one
|
// Use STRIPE_KEY environment variable
|
||||||
stripe.Key = "sk_test_51OxXuWP2nW0okNQyiNAOcBTTWZSiyP1el5KOmV3yIv1DQR0415YPsH1eb89SLrsOFj80o9p2AxGOy042e53yDvZN00jHxHAbE6"
|
stripe.Key = os.Getenv("STRIPE_KEY")
|
||||||
|
|
||||||
botTmpl = pongo2.Must(pongo2.FromFile("views/partials/message-bot.html"))
|
botTmpl = pongo2.Must(pongo2.FromFile("views/partials/message-bot.html"))
|
||||||
userTmpl = pongo2.Must(pongo2.FromFile("views/partials/message-user.html"))
|
userTmpl = pongo2.Must(pongo2.FromFile("views/partials/message-user.html"))
|
||||||
selectBtnTmpl = pongo2.Must(pongo2.FromFile("views/partials/model-selection-btn.html"))
|
selectBtnTmpl = pongo2.Must(pongo2.FromFile("views/partials/model-selection-btn.html"))
|
||||||
|
modelPopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/popover-models.html"))
|
||||||
|
conversationPopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/popover-conversation.html"))
|
||||||
|
usagePopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/popover-usage.html"))
|
||||||
|
settingPopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/popover-settings.html"))
|
||||||
|
messageEditTmpl = pongo2.Must(pongo2.FromFile("views/partials/message-edit-form.html"))
|
||||||
|
|
||||||
// Import HTML using django engine/template
|
// Import HTML using django engine/template
|
||||||
engine := django.New("./views", ".html")
|
engine := django.New("./views", ".html")
|
||||||
@ -82,11 +92,13 @@ func main() {
|
|||||||
// Create new Fiber instance
|
// Create new Fiber instance
|
||||||
app := fiber.New(fiber.Config{
|
app := fiber.New(fiber.Config{
|
||||||
Views: engine,
|
Views: engine,
|
||||||
AppName: "JADE 2.0",
|
AppName: "JADE",
|
||||||
EnablePrintRoutes: true,
|
EnablePrintRoutes: true,
|
||||||
})
|
})
|
||||||
|
defer app.Shutdown()
|
||||||
|
|
||||||
// Add default logger
|
// Add default logger
|
||||||
|
app.Use(favicon.New())
|
||||||
app.Use(logger.New())
|
app.Use(logger.New())
|
||||||
app.Use(recover.New())
|
app.Use(recover.New())
|
||||||
|
|
||||||
@ -118,7 +130,6 @@ func main() {
|
|||||||
app.Get("/loadConversationSelection", LoadConversationSelectionHandler)
|
app.Get("/loadConversationSelection", LoadConversationSelectionHandler)
|
||||||
app.Get("/refreshConversationSelection", RefreshConversationSelectionHandler)
|
app.Get("/refreshConversationSelection", RefreshConversationSelectionHandler)
|
||||||
app.Get("/loadUsageKPI", LoadUsageKPIHandler)
|
app.Get("/loadUsageKPI", LoadUsageKPIHandler)
|
||||||
app.Get("/loadKeys", LoadKeysHandler)
|
|
||||||
app.Get("/loadSettings", LoadSettingsHandler)
|
app.Get("/loadSettings", LoadSettingsHandler)
|
||||||
app.Post("/updateLLMPositionBatch", updateLLMPositionBatch)
|
app.Post("/updateLLMPositionBatch", updateLLMPositionBatch)
|
||||||
app.Get("/createConversation", CreateConversationHandler)
|
app.Get("/createConversation", CreateConversationHandler)
|
||||||
@ -175,7 +186,9 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Start server
|
// Start server
|
||||||
log.Fatal(app.Listen(":8080"))
|
if err := app.Listen(":8080"); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The route to add keys, idk where to put it so it's here
|
// The route to add keys, idk where to put it so it's here
|
||||||
|
BIN
static/favicon.ico
Normal file
BIN
static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 203 KiB |
@ -1,5 +1,5 @@
|
|||||||
body {
|
body {
|
||||||
padding-bottom: 155px;
|
padding-bottom: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
|
@ -57,9 +57,7 @@
|
|||||||
textarea.addEventListener('keydown', handleTextareaKeydown);
|
textarea.addEventListener('keydown', handleTextareaKeydown);
|
||||||
|
|
||||||
function toggleSendButton() {
|
function toggleSendButton() {
|
||||||
const sendButton = document.getElementById('chat-input-send-btn');
|
document.getElementById('chat-input-send-btn').disabled = textarea.value.trim().length === 0 || document.getElementsByClassName('selected icon-llm').length === 0;
|
||||||
const selectedLLMIds = JSON.parse(getSelectedModelsIDs());
|
|
||||||
sendButton.disabled = textarea.value.trim() === '' || selectedLLMIds.length === 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearTextArea() {
|
function clearTextArea() {
|
||||||
@ -75,12 +73,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleTextareaKeydown(event) {
|
function handleTextareaKeydown(event) {
|
||||||
if (event.metaKey && event.key === 'Enter') {
|
if (event.metaKey && event.key === 'Enter' && event.target === textarea && textarea.value.trim() !== '' && document.getElementsByClassName('selected icon-llm').length !== 0) {
|
||||||
// Check if the cursor is in the textarea
|
// Check if the cursor is in the textarea
|
||||||
if (event.target === textarea) {
|
|
||||||
// Trigger the same action as the send button
|
// Trigger the same action as the send button
|
||||||
document.getElementById('chat-input-send-btn').click();
|
document.getElementById('chat-input-send-btn').click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</script>
|
</script>
|
@ -86,6 +86,63 @@
|
|||||||
button.innerHTML = originalText;
|
button.innerHTML = originalText;
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lastSelectedIndex = null;
|
||||||
|
|
||||||
|
function toggleSelection(element) {
|
||||||
|
const elements = Array.from(document.getElementsByClassName('icon-llm'));
|
||||||
|
const index = elements.indexOf(element);
|
||||||
|
|
||||||
|
if (document.body.classList.contains('shift-pressed') && lastSelectedIndex !== null) {
|
||||||
|
const [start, end] = [lastSelectedIndex, index].sort((a, b) => a - b);
|
||||||
|
let allSelected = true;
|
||||||
|
for (let i = start; i <= end; i++) {
|
||||||
|
if (!elements[i].classList.contains('selected')) {
|
||||||
|
allSelected = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = start; i <= end; i++) {
|
||||||
|
if (allSelected) {
|
||||||
|
elements[i].classList.remove('selected');
|
||||||
|
elements[i].classList.add('unselected');
|
||||||
|
} else {
|
||||||
|
elements[i].classList.add('selected');
|
||||||
|
elements[i].classList.remove('unselected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastSelectedIndex = null;
|
||||||
|
|
||||||
|
const elements2 = Array.from(document.getElementsByClassName('icon-text'));
|
||||||
|
for (let i = 0; i < elements2.length; i++) {
|
||||||
|
elements2[i].classList.remove('shiftselected');
|
||||||
|
}
|
||||||
|
} else if (document.body.classList.contains('shift-pressed') && lastSelectedIndex === null) {
|
||||||
|
lastSelectedIndex = index;
|
||||||
|
element.classList.toggle('shiftselected');
|
||||||
|
} else {
|
||||||
|
element.classList.toggle('selected');
|
||||||
|
element.classList.toggle('unselected');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If at least one model is selected, enable the delete button
|
||||||
|
if (document.getElementsByClassName('selected icon-llm').length > 0) {
|
||||||
|
document.getElementById('delete-model-button').disabled = false;
|
||||||
|
} else {
|
||||||
|
document.getElementById('delete-model-button').disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleSendButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedModelsIDs() {
|
||||||
|
var selectedModelsIDs = [];
|
||||||
|
var selectedModels = document.getElementsByClassName('selected icon-llm');
|
||||||
|
for (var i = 0; i < selectedModels.length; i++) {
|
||||||
|
selectedModelsIDs.push(selectedModels[i].getAttribute('data-id'));
|
||||||
|
}
|
||||||
|
return selectedModelsIDs.length > 0 ? JSON.stringify(selectedModelsIDs) : '[]';
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -127,11 +127,13 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
document.getElementById('create-model-button').addEventListener('click', function () {
|
document.getElementById('create-model-button').addEventListener('click', function () {
|
||||||
|
console.log('create model');
|
||||||
document.getElementById('models-list').classList.add('is-hidden');
|
document.getElementById('models-list').classList.add('is-hidden');
|
||||||
document.getElementById('models-creation').classList.remove('is-hidden');
|
document.getElementById('models-creation').classList.remove('is-hidden');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('cancel-create-model-button').addEventListener('click', function () {
|
document.getElementById('cancel-create-model-button').addEventListener('click', function () {
|
||||||
|
console.log('cancel create model');
|
||||||
document.getElementById('models-list').classList.remove('is-hidden');
|
document.getElementById('models-list').classList.remove('is-hidden');
|
||||||
document.getElementById('models-creation').classList.add('is-hidden');
|
document.getElementById('models-creation').classList.add('is-hidden');
|
||||||
});
|
});
|
||||||
@ -161,68 +163,5 @@
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let lastSelectedIndex = null;
|
|
||||||
|
|
||||||
function toggleSelection(element) {
|
|
||||||
const elements = Array.from(document.getElementsByClassName('icon-llm'));
|
|
||||||
const index = elements.indexOf(element);
|
|
||||||
|
|
||||||
if (document.body.classList.contains('shift-pressed') && lastSelectedIndex !== null) {
|
|
||||||
const [start, end] = [lastSelectedIndex, index].sort((a, b) => a - b);
|
|
||||||
let allSelected = true;
|
|
||||||
for (let i = start; i <= end; i++) {
|
|
||||||
if (!elements[i].classList.contains('selected')) {
|
|
||||||
allSelected = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = start; i <= end; i++) {
|
|
||||||
if (allSelected) {
|
|
||||||
elements[i].classList.remove('selected');
|
|
||||||
elements[i].classList.add('unselected');
|
|
||||||
} else {
|
|
||||||
elements[i].classList.add('selected');
|
|
||||||
elements[i].classList.remove('unselected');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastSelectedIndex = null;
|
|
||||||
|
|
||||||
const elements2 = Array.from(document.getElementsByClassName('icon-text'));
|
|
||||||
for (let i = 0; i < elements2.length; i++) {
|
|
||||||
elements2[i].classList.remove('shiftselected');
|
|
||||||
}
|
|
||||||
} else if (document.body.classList.contains('shift-pressed') && lastSelectedIndex === null) {
|
|
||||||
lastSelectedIndex = index;
|
|
||||||
element.classList.toggle('shiftselected');
|
|
||||||
} else {
|
|
||||||
element.classList.toggle('selected');
|
|
||||||
element.classList.toggle('unselected');
|
|
||||||
}
|
|
||||||
|
|
||||||
// If at least one model is selected, enable the delete button
|
|
||||||
if (document.getElementsByClassName('selected icon-llm').length > 0) {
|
|
||||||
document.getElementById('delete-model-button').disabled = false;
|
|
||||||
} else {
|
|
||||||
document.getElementById('delete-model-button').disabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleSendButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSelectedModelsIDs() {
|
|
||||||
var selectedModelsIDs = [];
|
|
||||||
var selectedModels = document.getElementsByClassName('selected icon-llm');
|
|
||||||
for (var i = 0; i < selectedModels.length; i++) {
|
|
||||||
selectedModelsIDs.push(selectedModels[i].getAttribute('data-id'));
|
|
||||||
}
|
|
||||||
return selectedModelsIDs.length > 0 ? JSON.stringify(selectedModelsIDs) : '[]';
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleSendButton() {
|
|
||||||
var selectedModels = document.getElementsByClassName('selected');
|
|
||||||
var sendButton = document.getElementById('chat-input-send-btn');
|
|
||||||
sendButton.disabled = selectedModels.length === 0;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
Loading…
x
Reference in New Issue
Block a user