136 lines
4.2 KiB
Svelte
136 lines
4.2 KiB
Svelte
<script lang="ts">
|
|
import FileUpload from 'src/lib/FileUpload.svelte';
|
|
import Tabs from 'src/lib/Tabs.svelte';
|
|
import type { Model } from './+page.svelte';
|
|
import type { Class } from './types';
|
|
import { postFormData, get, showMessage } from 'src/lib/requests.svelte';
|
|
import ModelTable from './ModelTable.svelte';
|
|
import TrainModel from './TrainModel.svelte';
|
|
import ZipStructure from './ZipStructure.svelte';
|
|
import { notificationStore } from 'src/lib/NotificationsStore.svelte';
|
|
import { preventDefault } from 'src/lib/utils';
|
|
|
|
let {
|
|
model,
|
|
simple,
|
|
onreload = () => {}
|
|
}: { model: Model; simple?: boolean; onreload?: () => void } = $props();
|
|
|
|
let classes: Class[] = $state([]);
|
|
let has_data: boolean = $state(false);
|
|
|
|
let file: File | undefined = $state();
|
|
|
|
let uploading: Promise<void> = $state(Promise.resolve());
|
|
let numberOfInvalidImages = $state(0);
|
|
|
|
async function uploadZip() {
|
|
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/upload', form);
|
|
onreload();
|
|
} catch (e) {
|
|
showMessage(e, notificationStore, 'Could not upload data');
|
|
}
|
|
|
|
uploading = Promise.resolve();
|
|
}
|
|
|
|
$effect(() => {
|
|
getData();
|
|
});
|
|
|
|
async function getData() {
|
|
if (!model) return;
|
|
try {
|
|
let data = await get(`models/edit/classes?id=${model.id}`);
|
|
classes = data.classes;
|
|
numberOfInvalidImages = data.number_of_invalid_images;
|
|
has_data = data.has_data;
|
|
} catch (e) {
|
|
showMessage(e, notificationStore, 'Could not get information on classes');
|
|
}
|
|
}
|
|
</script>
|
|
|
|
{#if !simple}
|
|
<div class="card">
|
|
<h3>Training data</h3>
|
|
{#if classes.length == 0}
|
|
<p>You need to upload data so the model can train.</p>
|
|
<Tabs active="upload" let:isActive>
|
|
<div slot="buttons" let:setActive let:isActive>
|
|
<button class="tab" class:selected={isActive('upload')} onclick={setActive('upload')}>
|
|
Upload
|
|
</button>
|
|
<!--button
|
|
class="tab"
|
|
class:selected={isActive('create-class')}
|
|
onclick={setActive('create-class')}
|
|
>
|
|
Create Class
|
|
</button-->
|
|
<!--button class="tab" class:selected={isActive('api')} onclick={setActive('api')}>
|
|
Api
|
|
</button-->
|
|
</div>
|
|
<div class="content" class:selected={isActive('upload')}>
|
|
<form onsubmit={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.
|
|
<ZipStructure />
|
|
</div>
|
|
<FileUpload replace_slot bind: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>
|
|
{#if file}
|
|
{#await uploading}
|
|
<button disabled> Uploading </button>
|
|
{:then}
|
|
<button> Add </button>
|
|
{/await}
|
|
{/if}
|
|
</form>
|
|
</div>
|
|
<!--div class="content" class:selected={isActive('create-class')}>
|
|
<ModelTable {classes} {model} {onreload} />
|
|
</div-->
|
|
<!--div class="content" class:selected={isActive('api')}>TODO</div-->
|
|
</Tabs>
|
|
<div class="tabs"></div>
|
|
{:else}
|
|
<p>You need to upload data so the model can train.</p>
|
|
{#if numberOfInvalidImages > 0}
|
|
<p class="danger">
|
|
There are images {numberOfInvalidImages} that were loaded that do not have the correct format.
|
|
These images will be deleted when the model trains.
|
|
</p>
|
|
{/if}
|
|
<ModelTable {classes} {model} {onreload} />
|
|
{/if}
|
|
</div>
|
|
{/if}
|
|
|
|
{#if classes.some((item) => item.status == 1) && ![-6, 6].includes(model.status)}
|
|
<TrainModel number_of_invalid_images={numberOfInvalidImages} {model} {has_data} {onreload} />
|
|
{/if}
|