chore: added way to add new images

This commit is contained in:
2024-03-09 09:41:16 +00:00
parent 4a95f0211d
commit 0d37ba8d59
12 changed files with 510 additions and 176 deletions

View File

@@ -14,7 +14,7 @@
<div class="tab-buttons">
<slot name="buttons" {setActive} {isActive} />
</div>
<slot {isActive} />
<slot {isActive} {active} />
</div>
<style lang="scss">
@@ -29,6 +29,11 @@
.tab-buttons {
display: flex;
overflow-x: scroll;
width: 100%;
:global(.buttons) {
width: 100%;
}
:global(.tab) {
padding: 5px;

View File

@@ -6,6 +6,8 @@
width: number;
height: number;
status: number;
model_type: number;
format: string;
};
export type Layer = {
@@ -286,9 +288,20 @@
{/await}
<!-- TODO Add ability to stop training -->
</div>
{:else if m.status == 5}
{:else if [5, 6, -6].includes(m.status)}
<BaseModelInfo model={m} />
<RunModel model={m} />
{#if m.status == 6}
<div class="card">
Model expading... Processing ZIP file
</div>
{/if}
{#if m.status == -6}
<DeleteZip model={m} on:reload={getModel} expand />
{/if}
{#if m.model_type == 2}
<ModelData model={m} on:reload={getModel} />
{/if}
<DeleteModel model={m} />
{:else}
<h1>Unknown Status of the model.</h1>

View File

@@ -6,12 +6,12 @@
let message: MessageSimple;
let { model } = $props<{model: Model}>();
let { model, expand } = $props<{model: Model, expand?: boolean}>();
const dispatch = createEventDispatcher<{reload: void}>();
async function deleteZip() {
message.display("");
message.clear();
try {
await rdelete("models/data/delete-zip-file", { id: model.id });
@@ -28,9 +28,15 @@
<form on:submit|preventDefault={deleteZip}>
Failed to proccess the zip file.<br/>
Delete file and proccess again.<br/>
<br/>
{#if expand}
Failed to proccess the zip file.<br/>
Delete file and upload a correct version do add more classes.<br/>
<br/>
{:else}
Failed to proccess the zip file.<br/>
Delete file and proccess again.<br/>
<br/>
{/if}
<div class="spacer" ></div>
<MessageSimple bind:this={message} />
<button class="danger">

View File

@@ -2,6 +2,7 @@
export type Class = {
name: string;
id: string;
status: number;
}
</script>
<script lang="ts">
@@ -153,7 +154,7 @@
</form>
</div>
<div class="content" class:selected={isActive("create-class")}>
<ModelTable {classes} {model} />
<ModelTable {classes} {model} on:reload={() => dispatch('reload')} />
</div>
<div class="content" class:selected={isActive("api")}>
TODO
@@ -180,7 +181,7 @@
</button>
</div>
<div class="content" class:selected={isActive("create-class")}>
<ModelTable {classes} {model} />
<ModelTable {classes} {model} on:reload={() => dispatch('reload')} />
</div>
<div class="content" class:selected={isActive("api")}>
TODO

View File

@@ -3,14 +3,20 @@
file_path: string;
mode: number;
status: number;
id: string;
};
</script>
<script lang="ts">
import Tabs from 'src/lib/Tabs.svelte';
import type { Class } from './ModelData.svelte';
import { get } from 'src/lib/requests.svelte';
import { get, postFormData } from 'src/lib/requests.svelte';
import type { Model } from './+page.svelte';
import FileUpload from 'src/lib/FileUpload.svelte';
import MessageSimple from 'src/lib/MessageSimple.svelte';
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher<{reload: void}>();
let selected_class: Class | undefined = $state();
@@ -22,7 +28,6 @@
function setActiveClass(c: Class, tb_fn: (name: string) => () => void) {
selected_class = c;
console.log('test', c, classes, c.name);
tb_fn(c.name)();
}
@@ -31,8 +36,6 @@
});
async function getList() {
console.log(selected_class);
try {
let url = new URLSearchParams();
url.append('id', selected_class?.id ?? '');
@@ -59,101 +62,231 @@
getList();
}
});
let file: File | undefined = $state();
let uploadImage: MessageSimple;
let uploading = $state(Promise.resolve());
async function uploadZip() {
uploadImage.clear();
if (!file) return;
uploading = new Promise(() => {});
let form = new FormData();
form.append('id', model.id);
form.append('file', file, 'upload.zip');
try {
await postFormData('models/data/class/upload', form);
dispatch('reload');
} catch (e) {
if (e instanceof Response) {
uploadImage.display(await e.json());
} else {
uploadImage.display('');
}
}
uploading = Promise.resolve();
}
</script>
{#if classes.length == 0}
TODO CREATE TABLE
{:else}
<Tabs active={classes[0]?.name} let:isActive>
<div slot="buttons" let:setActive let:isActive>
<div class="buttons" slot="buttons" let:setActive let:isActive>
<!-- TODO Auto Load 1st -->
{#each classes as item}
<button
on:click={() => setActiveClass(item, setActive)}
class="tab"
class:selected={isActive(item.name)}
>
{item.name}
</button>
{/each}
<div>
{#each classes as item}
<button
on:click={() => setActiveClass(item, setActive)}
class="tab"
class:selected={isActive(item.name)}
>
{item.name}
</button>
{/each}
</div>
<button on:click={() => {
setActive("-----New Class-----")();
selected_class = undefined;
}}>
<span class="bi bi-plus" />
</button>
</div>
<div class="content selected">
<table>
<thead>
<tr>
<th> File Path </th>
<th> Mode </th>
<th>
<!-- Img -->
</th>
<th>
<!-- Status -->
</th>
</tr>
</thead>
<tbody>
{#each image_list as image}
<tr>
<td>
{#if image.file_path == 'id://'}
Managed
{:else}
{image.file_path}
{/if}
</td>
<td>
{#if image.mode == 2}
Testing
{:else}
Training
{/if}
</td>
<td class="text-center">
{#if image.file_path == 'id://'}
<img
alt=""
src="/api/savedData/{model.id}/data/{image.id}.{model.format}"
height="30px"
width="30px"
style="object-fit: contain;"
/>
{:else}
TODO img {image.file_path}
{/if}
</td>
<td class="text-center">
{#if image.status == 1}
<span class="bi bi-check-circle-fill" style="color: green"></span>
{:else}
<span class="bi bi-exclamation-triangle-fill" style="color: red"></span>
{/if}
</td>
</tr>
{/each}
</tbody>
</table>
<div class="flex justify-center align-center">
<div class="grow-1 flex justify-end align-center">
{#if page > 0}
<button on:click={() => (page -= 1)}> Prev </button>
{/if}
</div>
{#if selected_class == undefined && isActive('-----New Class-----')}
<div class="content selected">
<h2>
Add New Class
</h2>
<form on:submit|preventDefault={uploadZip}>
<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>
<FileUpload replace_slot bind:file={file} accept="application/zip" notExpand >
<img src="/imgs/upload-icon.png" alt="" />
<span>
Upload Zip File
</span>
<div slot="replaced" style="display: inline;">
<img src="/imgs/upload-icon.png" alt="" />
<span>
File selected
</span>
</div>
</FileUpload>
</fieldset>
<MessageSimple bind:this={uploadImage} />
{#await uploading}
<button disabled>
Uploading
</button>
{:then}
<button>
Add
</button>
{/await}
</form>
</div>
{/if}
{#if selected_class}
<div class="content selected">
{#if model.model_type == 2}
{#if selected_class?.status == 1}
<h2>
Class to train
</h2>
{:else if selected_class?.status == 2}
<h2>
Class training
</h2>
{:else if selected_class?.status == 3}
<h2>
Class trained
</h2>
{/if}
{/if}
<table>
<thead>
<tr>
<th> File Path </th>
<th> Mode </th>
<th>
<!-- Img -->
</th>
<th>
<!-- Status -->
</th>
</tr>
</thead>
<tbody>
{#each image_list as image}
<tr>
<td>
{#if image.file_path == 'id://'}
Managed
{:else}
{image.file_path}
{/if}
</td>
<td>
{#if image.mode == 2}
Testing
{:else}
Training
{/if}
</td>
<td class="text-center">
{#if image.file_path == 'id://'}
<img
alt=""
src="/api/savedData/{model.id}/data/{image.id}.{model.format}"
height="30px"
width="30px"
style="object-fit: contain;"
/>
{:else}
TODO img {image.file_path}
{/if}
</td>
<td class="text-center">
{#if image.status == 1}
<span class="bi bi-check-circle-fill" style="color: green"></span>
{:else}
<span class="bi bi-exclamation-triangle-fill" style="color: red"></span>
{/if}
</td>
</tr>
{/each}
</tbody>
</table>
<div class="flex justify-center align-center">
<div class="grow-1 flex justify-end align-center">
{#if page > 0}
<button on:click={() => (page -= 1)}> Prev </button>
{/if}
</div>
<div style="padding: 10px;">
{page}
</div>
<div style="padding: 10px;">
{page}
</div>
<div class="grow-1 flex justify-start align-center">
{#if showNext}
<button on:click={() => (page += 1)}> Next </button>
{/if}
</div>
</div>
</div>
<div class="grow-1 flex justify-start align-center">
{#if showNext}
<button on:click={() => (page += 1)}> Next </button>
{/if}
</div>
</div>
</div>
{/if}
</Tabs>
{/if}
<style lang="scss">
.buttons {
width: 100%;
display: flex;
justify-content: space-between;
&>button {
margin: 3px 5px;
}
}
table {
width: 100%;
box-shadow: 0 2px 8px 1px #66666622;