working notifications across backend and frontend
This commit is contained in:
@ -237,6 +237,11 @@ func ListenNewStackEvents(db *sql.DB) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := stackModel.EndProcessing(ctx, stackID); err != nil {
|
||||
newStacksLogger.Error("failed to finish processing", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
newStacksLogger.Debug("Finished processing stack", "StackID", stackID)
|
||||
}()
|
||||
}
|
||||
|
@ -121,6 +121,16 @@ func (m ListModel) StartProcessing(ctx context.Context, processingListID uuid.UU
|
||||
return err
|
||||
}
|
||||
|
||||
func (m ListModel) EndProcessing(ctx context.Context, processingListID uuid.UUID) error {
|
||||
startProcessingStmt := ProcessingLists.
|
||||
UPDATE(ProcessingLists.Status).
|
||||
SET(model.Progress_Complete).
|
||||
WHERE(ProcessingLists.ID.EQ(UUID(processingListID)))
|
||||
|
||||
_, err := startProcessingStmt.ExecContext(ctx, m.dbPool)
|
||||
return err
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// INSERT methods
|
||||
// ========================================
|
||||
|
@ -8,7 +8,8 @@ export const ProcessingImages: Component = () => {
|
||||
const notifications = useNotifications();
|
||||
|
||||
const processingNumber = () =>
|
||||
Object.keys(notifications.state.ProcessingImages).length;
|
||||
Object.keys(notifications.state.ProcessingImages).length +
|
||||
Object.keys(notifications.state.ProcessingLists).length;
|
||||
|
||||
return (
|
||||
<Popover sameWidth gutter={4}>
|
||||
@ -16,7 +17,7 @@ export const ProcessingImages: Component = () => {
|
||||
<Show when={processingNumber() > 0}>
|
||||
<p class="text-md">
|
||||
Processing {processingNumber()}{" "}
|
||||
{processingNumber() === 1 ? "image" : "images"}
|
||||
{processingNumber() === 1 ? "item" : "items"}
|
||||
...
|
||||
</p>
|
||||
</Show>
|
||||
@ -30,10 +31,8 @@ export const ProcessingImages: Component = () => {
|
||||
<Popover.Portal>
|
||||
<Popover.Content class="shadow-2xl flex flex-col gap-2 bg-white rounded-xl p-2">
|
||||
<Show
|
||||
when={
|
||||
Object.entries(notifications.state.ProcessingImages).length > 0
|
||||
}
|
||||
fallback={<p>No images to process</p>}
|
||||
when={processingNumber() > 0}
|
||||
fallback={<p>No items to process</p>}
|
||||
>
|
||||
<For each={Object.entries(notifications.state.ProcessingImages)}>
|
||||
{([id, _image]) => (
|
||||
@ -57,6 +56,24 @@ export const ProcessingImages: Component = () => {
|
||||
</Show>
|
||||
)}
|
||||
</For>
|
||||
|
||||
<For each={Object.entries(notifications.state.ProcessingLists)}>
|
||||
{([, _list]) => (
|
||||
<Show when={_list}>
|
||||
{(list) => (
|
||||
<div class="flex gap-2 w-full justify-center">
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="text-slate-900">New Stack: {list().Name}</p>
|
||||
</div>
|
||||
<LoadingCircle
|
||||
status="loading"
|
||||
class="ml-auto self-center"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Show>
|
||||
)}
|
||||
</For>
|
||||
</Show>
|
||||
</Popover.Content>
|
||||
</Popover.Portal>
|
||||
|
@ -10,18 +10,27 @@ import {
|
||||
useContext,
|
||||
} from "solid-js";
|
||||
import { base } from "@network/index";
|
||||
import { processingImagesValidator } from "@network/notifications";
|
||||
import {
|
||||
notificationValidator,
|
||||
processingImagesValidator,
|
||||
processingListValidator,
|
||||
} from "@network/notifications";
|
||||
|
||||
type NotificationState = {
|
||||
ProcessingImages: Record<
|
||||
string,
|
||||
InferOutput<typeof processingImagesValidator> | undefined
|
||||
>;
|
||||
ProcessingLists: Record<
|
||||
string,
|
||||
InferOutput<typeof processingListValidator> | undefined
|
||||
>;
|
||||
};
|
||||
|
||||
export const Notifications = (onCompleteImage: () => void) => {
|
||||
const [state, setState] = createStore<NotificationState>({
|
||||
ProcessingImages: {},
|
||||
ProcessingLists: {},
|
||||
});
|
||||
|
||||
const { processingImages } = useSearchImageContext();
|
||||
@ -45,21 +54,32 @@ export const Notifications = (onCompleteImage: () => void) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const processingImage = safeParse(processingImagesValidator, jsonData);
|
||||
if (!processingImage.success) {
|
||||
const notification = safeParse(notificationValidator, jsonData);
|
||||
if (!notification.success) {
|
||||
console.error("Processing image could not be parsed.", e.data);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("SSE: ", processingImage);
|
||||
console.log("SSE: ", notification);
|
||||
|
||||
const { ImageID, Status } = processingImage.output;
|
||||
if (notification.output.Type === "image") {
|
||||
const { ImageID, Status } = notification.output;
|
||||
|
||||
if (Status === "complete") {
|
||||
setState("ProcessingImages", ImageID, undefined);
|
||||
onCompleteImage();
|
||||
} else {
|
||||
setState("ProcessingImages", ImageID, processingImage.output);
|
||||
if (Status === "complete") {
|
||||
setState("ProcessingImages", ImageID, undefined);
|
||||
onCompleteImage();
|
||||
} else {
|
||||
setState("ProcessingImages", ImageID, notification.output);
|
||||
}
|
||||
} else if (notification.output.Type === "list") {
|
||||
const { ListID, Status } = notification.output;
|
||||
|
||||
if (Status === "complete") {
|
||||
setState("ProcessingLists", ListID, undefined);
|
||||
onCompleteImage();
|
||||
} else {
|
||||
setState("ProcessingLists", ListID, notification.output);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -83,6 +103,7 @@ export const Notifications = (onCompleteImage: () => void) => {
|
||||
images.map((i) => [
|
||||
i.ImageID,
|
||||
{
|
||||
Type: "image",
|
||||
ImageID: i.ImageID,
|
||||
ImageName: i.Image.ImageName,
|
||||
Status: i.Status,
|
||||
|
@ -1,6 +1,21 @@
|
||||
import { literal, pipe, strictObject, string, union, uuid } from "valibot";
|
||||
|
||||
export const processingListValidator = strictObject({
|
||||
Type: literal("list"),
|
||||
|
||||
Name: string(),
|
||||
ListID: pipe(string(), uuid()),
|
||||
|
||||
Status: union([
|
||||
literal("not-started"),
|
||||
literal("in-progress"),
|
||||
literal("complete"),
|
||||
]),
|
||||
});
|
||||
|
||||
export const processingImagesValidator = strictObject({
|
||||
Type: literal("image"),
|
||||
|
||||
ImageID: pipe(string(), uuid()),
|
||||
ImageName: string(),
|
||||
Status: union([
|
||||
@ -9,3 +24,8 @@ export const processingImagesValidator = strictObject({
|
||||
literal("complete"),
|
||||
]),
|
||||
});
|
||||
|
||||
export const notificationValidator = union([
|
||||
processingListValidator,
|
||||
processingImagesValidator,
|
||||
]);
|
||||
|
Reference in New Issue
Block a user