feat: closes #11 and fixed database cons remaining open
This commit is contained in:
@@ -1,3 +1,47 @@
|
||||
function tabs() {
|
||||
for (const elm of document.querySelectorAll(".tabs")) {
|
||||
let count = 0;
|
||||
let selected = 0;
|
||||
for (const child of elm.children) {
|
||||
if (child.tagName == "BUTTON") {
|
||||
count++;
|
||||
if (child.classList.contains("selected")) {
|
||||
selected++;
|
||||
}
|
||||
if (!child.getAttribute("data-armed")) {
|
||||
child.addEventListener("click", () => {
|
||||
if (!child.classList.contains("selected")) {
|
||||
for (const elm of child.parentElement.children) {
|
||||
elm.classList.remove("selected");
|
||||
}
|
||||
child.classList.add("selected");
|
||||
document.querySelector(`.tabs .content[data-tab="${
|
||||
child.getAttribute("data-tab")
|
||||
}"]`)?.classList.add("selected");
|
||||
}
|
||||
});
|
||||
child.setAttribute("data-armed", "true")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selected > 1 || selected == 0) {
|
||||
for (const child of elm.children) {
|
||||
child.classList.remove("selected");
|
||||
}
|
||||
for (const child of elm.children) {
|
||||
if (child.tagName == "BUTTON") {
|
||||
child.classList.add("selected");
|
||||
document.querySelector(`.tabs .content[data-tab="${
|
||||
child.getAttribute("data-tab")
|
||||
}"]`)?.classList.add("selected");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
function load() {
|
||||
for (const elm of document.querySelectorAll("form > button")) {
|
||||
elm.addEventListener('click', (e) => {
|
||||
@@ -35,6 +79,7 @@ function load() {
|
||||
}
|
||||
});
|
||||
}
|
||||
tabs();
|
||||
}
|
||||
window.onload = load;
|
||||
htmx.on('htmx:afterSwap', load);
|
||||
|
||||
@@ -43,9 +43,103 @@
|
||||
{{ end }}
|
||||
|
||||
{{ define "data-model-card" }}
|
||||
<form hx-delete="/models/train" hx-headers='{"REQUEST-TYPE": "html"}' hx-swap="outerHTML" {{ if .Error }} class="submitted" {{end}} >
|
||||
data menu
|
||||
</form>
|
||||
<div class="card">
|
||||
<h3>
|
||||
Training data
|
||||
</h3>
|
||||
{{ if eq (len .Classes) 0 }}
|
||||
<p>
|
||||
You need to upload data so the model can train.
|
||||
</p>
|
||||
<div class="tabs">
|
||||
<button class="tab" data-tab="upload">
|
||||
Upload
|
||||
</button>
|
||||
<button class="tab" data-tab="create_class">
|
||||
Create Class
|
||||
</button>
|
||||
<button class="tab" data-tab="api">
|
||||
Api
|
||||
</button>
|
||||
<div class="content" data-tab="upload">
|
||||
<form hx-headers='{"REQUEST-TYPE": "htmlfull"}' enctype="multipart/form-data" hx-post="/models/data/upload">
|
||||
<input type="hidden" name="id" value={{.Model.Id}} />
|
||||
<fieldset class="file-upload" >
|
||||
<label for="file">Data file</label>
|
||||
<div class="form-msg">
|
||||
Please provide a file that has the training and testing data<br/>
|
||||
The file must have 2 folders one with testing images and one with training images. <br/>
|
||||
Each of the folders will contain the classes of the model. The folders must be the same in testing and training.
|
||||
The class folders must have the images for the classes.
|
||||
<pre>
|
||||
training\
|
||||
class1\
|
||||
img1.png
|
||||
img2.png
|
||||
img2.png
|
||||
...
|
||||
class2\
|
||||
img1.png
|
||||
img2.png
|
||||
img2.png
|
||||
...
|
||||
...
|
||||
testing\
|
||||
class1\
|
||||
img1.png
|
||||
img2.png
|
||||
img2.png
|
||||
...
|
||||
class2\
|
||||
img1.png
|
||||
img2.png
|
||||
img2.png
|
||||
...
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
<div class="icon-holder">
|
||||
<button class="icon">
|
||||
<img replace="icon" src="/imgs/upload-icon.png" />
|
||||
<span replace="File Selected">
|
||||
Upload Zip File
|
||||
</span>
|
||||
</button>
|
||||
<input id="file" name="file" type="file" required accept="application/zip" />
|
||||
</div>
|
||||
</fieldset>
|
||||
<button>
|
||||
Add
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="content" data-tab="create_class">
|
||||
TODO
|
||||
</div>
|
||||
<div class="content" data-tab="api">
|
||||
TODO
|
||||
</div>
|
||||
</div>
|
||||
{{ else }}
|
||||
<p>
|
||||
You need to upload data so the model can train.
|
||||
</p>
|
||||
<div class="tabs">
|
||||
<button class="tab" data-tab="create_class">
|
||||
Create Class
|
||||
</button>
|
||||
<button class="tab" data-tab="api">
|
||||
Api
|
||||
</button>
|
||||
<div class="content" data-tab="create_class">
|
||||
TODO
|
||||
</div>
|
||||
<div class="content" data-tab="api">
|
||||
TODO
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{ define "train-model-card" }}
|
||||
@@ -83,11 +177,33 @@
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
{{/* PRE TRAINING STATUS */}}
|
||||
{{ else if (eq .Model.Status 2) }}
|
||||
{{ template "base-model-card" . }}
|
||||
{{ template "data-model-card" . }}
|
||||
{{ template "train-model-card" . }}
|
||||
{{ template "delete-model-card" . }}
|
||||
{{/* FAILED TO PROCCESS THE ZIPFILE */}}
|
||||
{{ else if (eq .Model.Status -2)}}
|
||||
{{ template "base-model-card" . }}
|
||||
<form hx-delete="/models/data/delete-zip-file" hx-headers='{"REQUEST-TYPE": "html"}' hx-swap="outerHTML">
|
||||
Failed to proccess the zip file.<br/>
|
||||
Delete file and proccess afain.<br/>
|
||||
<br/>
|
||||
<div class="spacer" ></div>
|
||||
<input type="hidden" name="id" value="{{ .Model.Id }}" />
|
||||
<button class="danger">
|
||||
Delete Zip File
|
||||
</button>
|
||||
</form>
|
||||
{{ template "delete-model-card" . }}
|
||||
{{/* PROCCESS THE ZIPFILE */}}
|
||||
{{ else if (eq .Model.Status 3)}}
|
||||
{{ template "base-model-card" . }}
|
||||
<div class="card" hx-get="/models/edit?id={{ .Model.Id }}" hx-headers='{"REQUEST-TYPE": "htmlfull"}' hx-push="true" hx-swap="outerHTML" hx-target=".app" hx-trigger="load delay:2s" >
|
||||
{{/* TODO improve this */}}
|
||||
Processing zip file...
|
||||
</div>
|
||||
{{ else }}
|
||||
<h1>
|
||||
Unknown Status of the model.
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
:root {
|
||||
--white: #ffffff;
|
||||
--grey: #ffffff;
|
||||
--grey: #dbdcde;
|
||||
--light-grey: #fafafa;
|
||||
--main: #fca311;
|
||||
--sec: #14213d;
|
||||
--black: #000000;
|
||||
@@ -145,6 +146,12 @@ form {
|
||||
box-shadow: 2px 5px 8px 2px #66666655;
|
||||
}
|
||||
|
||||
.card form {
|
||||
padding: 0;
|
||||
border-radius: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
form label {
|
||||
display: block;
|
||||
padding-bottom: 5px;
|
||||
@@ -315,6 +322,11 @@ table tr td .button {
|
||||
box-shadow: 0 2px 5px 1px #66666655;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.card h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* Model stuff */
|
||||
@@ -333,3 +345,36 @@ table tr td .button {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
/* Tabs code */
|
||||
.tabs {
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
box-shadow: 0 2px 8px 1px #66666655;
|
||||
gap: 0 5px;
|
||||
}
|
||||
|
||||
.tabs .content {
|
||||
display: none;
|
||||
padding: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tabs .tab {
|
||||
padding: 5px;
|
||||
background: var(--light-grey);
|
||||
border-radius: 5px 5px 0 0;
|
||||
box-shadow: none;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.tabs .tab.selected {
|
||||
box-shadow: inset 0 2px 8px 1px #66666655;
|
||||
}
|
||||
|
||||
.tabs .content.selected {
|
||||
display: block;
|
||||
box-shadow: 0 2px 2px 1px #66666655;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user