@@ -8,63 +8,59 @@ import { onMount } from 'svelte';
88import { studioClient } from ' /@/utils/client' ;
99import { tasks } from ' /@/stores/tasks' ;
1010import type { Task } from ' @shared/src/models/ITask' ;
11- import { filterByLabel } from ' /@/utils/taskUtils' ;
12- import TasksProgress from ' /@/lib/progress/TasksProgress.svelte' ;
1311import { inferenceServers } from ' /@/stores/inferenceServers' ;
1412import type { ContainerProviderConnectionInfo } from ' @shared/src/models/IContainerConnectionInfo' ;
1513import { Button , ErrorMessage , FormPage , Input } from ' @podman-desktop/ui-svelte' ;
1614import ModelSelect from ' ../lib/select/ModelSelect.svelte' ;
1715import { containerProviderConnections } from ' /@/stores/containerProviderConnections' ;
1816import ContainerProviderConnectionSelect from ' /@/lib/select/ContainerProviderConnectionSelect.svelte' ;
1917import ContainerConnectionWrapper from ' /@/lib/notification/ContainerConnectionWrapper.svelte' ;
20- import { get } from ' svelte/store ' ;
18+ import TrackedTasks from ' /@/lib/progress/TrackedTasks.svelte ' ;
2119
22- // The tracking id is a unique identifier provided by the
23- // backend when calling requestCreateInferenceServer
24- export let trackingId: string | undefined = undefined ;
20+ interface Props {
21+ // The tracking id is a unique identifier provided by the
22+ // backend when calling requestCreateInferenceServer
23+ trackingId? : string ;
24+ }
25+
26+ let { trackingId }: Props = $props ();
2527
2628// List of the models available locally
27- let localModels: ModelInfo [];
28- $ : localModels = $modelsInfo .filter (model => model .file );
29+ let localModels: ModelInfo [] = $derived ($modelsInfo .filter (model => model .file ));
2930
3031// The container provider connection to use
31- let containerProviderConnection: ContainerProviderConnectionInfo | undefined = undefined ;
32+ let containerProviderConnection: ContainerProviderConnectionInfo | undefined = $state ( undefined ) ;
3233
3334// Filtered connections (started)
34- let startedContainerProviderConnectionInfo: ContainerProviderConnectionInfo [] = [];
35- $ : startedContainerProviderConnectionInfo = $containerProviderConnections .filter (
36- connection => connection .status === ' started' ,
35+ let startedContainerProviderConnectionInfo: ContainerProviderConnectionInfo [] = $derived (
36+ $containerProviderConnections .filter (connection => connection .status === ' started' ),
3737);
3838
39- // Select default connection
40- $ : if (containerProviderConnection === undefined && startedContainerProviderConnectionInfo .length > 0 ) {
41- containerProviderConnection = startedContainerProviderConnectionInfo [0 ];
42- }
43-
4439// The containerPort is the bind value to form input
45- let containerPort: number | undefined = undefined ;
40+ let containerPort: number | undefined = $state ( undefined ) ;
4641// The model is the bind value to ModelSelect form
47- let model: ModelInfo | undefined = undefined ;
42+ let model: ModelInfo | undefined = $state ( undefined ) ;
4843// If the creation of a new inference service fail
49- let errorMsg: string | undefined = undefined ;
50- // The trackedTasks are the tasks linked to the trackingId
51- let trackedTasks: Task [];
52-
53- // has an error been raised
54- let error: boolean = false ;
55-
44+ let errorMsg: string | undefined = $state (undefined );
5645// The containerId will be included in the tasks when the creation
5746// process will be completed
58- let containerId: string | undefined = undefined ;
59- $ : available = containerId && $inferenceServers .some (server => server .container .containerId );
60-
61- $ : loading = trackingId !== undefined && ! error ;
62-
63- $ : {
47+ let containerId: string | undefined = $state (undefined );
48+ // available means the server is started
49+ let available: boolean = $derived (!! containerId && $inferenceServers .some (server => server .container .containerId ));
50+ // loading state
51+ let loading = $derived (trackingId !== undefined && ! errorMsg );
52+
53+ $effect (() => {
54+ // Select default model
6455 if (! model && localModels .length > 0 ) {
6556 model = localModels [0 ];
6657 }
67- }
58+
59+ // Select default connection
60+ if (! containerProviderConnection && startedContainerProviderConnectionInfo .length > 0 ) {
61+ containerProviderConnection = startedContainerProviderConnectionInfo [0 ];
62+ }
63+ });
6864
6965const onContainerPortInput = (event : Event ): void => {
7066 const raw = (event .target as HTMLInputElement ).value ;
@@ -83,11 +79,10 @@ const submit = async (): Promise<void> => {
8379 if (containerPort === undefined ) throw new Error (' invalid container port' );
8480
8581 try {
86- error = false ;
8782 const trackingId = await studioClient .requestCreateInferenceServer ({
88- modelsInfo: [model ],
89- port: containerPort ,
90- connection: containerProviderConnection ,
83+ modelsInfo: [$state . snapshot ( model ) ],
84+ port: $state . snapshot ( containerPort ) ,
85+ connection: $state . snapshot ( containerProviderConnection ) ,
9186 });
9287 router .location .query .set (' trackingId' , trackingId );
9388 } catch (err : unknown ) {
@@ -107,32 +102,23 @@ const openServiceDetails = (): void => {
107102};
108103
109104// Utility method to filter the tasks properly based on the tracking Id
110- const processTasks = (tasks : Task []): void => {
111- if (trackingId === undefined ) {
112- trackedTasks = [];
113- return ;
114- }
115-
116- trackedTasks = filterByLabel (tasks , {
117- trackingId: trackingId ,
118- });
119-
105+ const processTasks = (trackedTasks : Task []): void => {
120106 // Check for errors
121107 // hint: we do not need to display them as the TasksProgress component will
122- error = trackedTasks .find (task => task .error )?.error !== undefined ;
108+ errorMsg = trackedTasks .find (task => task .error )?.error ;
123109
124110 const task: Task | undefined = trackedTasks .find (task => ' containerId' in (task .labels ?? {}));
125111 if (task === undefined ) return ;
126112
127113 containerId = task .labels ?.[' containerId' ];
128114
129115 // if we re-open the page, we might need to restore the model selected
130- populateModelFromTasks ();
116+ populateModelFromTasks (trackedTasks );
131117};
132118
133119// This method uses the trackedTasks to restore the selected value of model
134120// It is useful when the page has been restored
135- function populateModelFromTasks(): void {
121+ function populateModelFromTasks(trackedTasks : Task [] ): void {
136122 const task = trackedTasks .find (
137123 task => task .labels && ' model-id' in task .labels && typeof task .labels [' model-id' ] === ' string' ,
138124 );
@@ -145,26 +131,21 @@ function populateModelFromTasks(): void {
145131 model = mModel ;
146132}
147133
148- $ : if (typeof trackingId === ' string' && trackingId .length > 0 ) {
149- refreshTasks ();
150- }
151-
152- function refreshTasks(): void {
153- processTasks (get (tasks ));
154- }
155-
156- onMount (async () => {
157- containerPort = await studioClient .getHostFreePort ();
134+ onMount (() => {
135+ studioClient
136+ .getHostFreePort ()
137+ .then (port => {
138+ containerPort = port ;
139+ })
140+ .catch ((err : unknown ) => {
141+ console .error (err );
142+ });
158143
159144 // we might have a query parameter, then we should use it
160145 const queryModelId = router .location .query .get (' model-id' );
161146 if (queryModelId !== undefined && typeof queryModelId === ' string' ) {
162147 model = localModels .find (mModel => mModel .id === queryModelId );
163148 }
164-
165- tasks .subscribe (tasks => {
166- processTasks (tasks );
167- });
168149});
169150
170151export function goToUpPage(): void {
@@ -189,16 +170,14 @@ export function goToUpPage(): void {
189170 <!-- warning machine resources -->
190171 {#if containerProviderConnection }
191172 <div class =" mx-5" >
192- <ContainerConnectionWrapper model ={model } containerProviderConnection ={containerProviderConnection } />
173+ <ContainerConnectionWrapper
174+ model ={$state .snapshot (model )}
175+ containerProviderConnection ={$state .snapshot (containerProviderConnection )} />
193176 </div >
194177 {/if }
195178
196179 <!-- tasks tracked -->
197- {#if trackedTasks ?.length > 0 }
198- <div class =" mx-5 mt-5" role =" status" >
199- <TasksProgress tasks ={trackedTasks } />
200- </div >
201- {/if }
180+ <TrackedTasks onChange ={processTasks } class ="mx-5 mt-5" trackingId ={trackingId } tasks ={$tasks } />
202181
203182 <!-- form -->
204183 <div class =" bg-[var(--pd-content-card-bg)] m-5 space-y-6 px-8 sm:pb-6 xl:pb-8 rounded-lg h-fit" >
0 commit comments