Skip to content

Commit

Permalink
chore: completed creation flow
Browse files Browse the repository at this point in the history
  • Loading branch information
jeafreezy committed Nov 1, 2024
1 parent 45fc8f8 commit 99f6220
Show file tree
Hide file tree
Showing 18 changed files with 329 additions and 52 deletions.
3 changes: 3 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ dist-ssr
*.njsproj
*.sln
*.sw?

tsconfig.app.tsbuildinfo
tsconfig.node.tsbuildinfo
59 changes: 57 additions & 2 deletions frontend/src/app/providers/model-creation-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import { UseMutationResult } from "@tanstack/react-query";
import React, { createContext, useContext, useEffect, useState } from "react";
import { useToast } from "./toast-provider";
import { useNavigate } from "react-router-dom";
import { TTrainingDataset } from "@/types";
import { TModel, TTrainingDataset } from "@/types";
import { TCreateTrainingDatasetArgs } from "@/features/model-creation/api/create-trainings";
import { useCreateModel, useCreateModelTrainingRequest } from "@/features/model-creation/hooks/use-models";
import { TCreateModelArgs } from "@/features/model-creation/api/create-models";

// The names here is the same with the initialFormState object keys as well as the form validation config
export enum MODEL_CREATION_FORM_NAME {
Expand All @@ -30,6 +32,7 @@ export enum MODEL_CREATION_FORM_NAME {
TMS_URL = "tmsURL",
TMS_URL_VALIDITY = "tmsURLValidation",
SELECTED_TRAINING_DATASET_ID = "selectedTrainingDatasetId",
TRAINING_AREAS = "trainingAreas",
}

export const FORM_VALIDATION_CONFIG = {
Expand Down Expand Up @@ -81,6 +84,7 @@ const initialFormState = {
// training dataset selection
selectedTrainingDatasetId: "",
zoomLevels: [20, 21],
trainingAreas: [],
// Defaults to basic configurations
trainingType: TrainingType.BASIC,
epoch: 2,
Expand All @@ -107,6 +111,12 @@ const ModelCreationFormContext = createContext<{
TCreateTrainingDatasetArgs,
unknown
>;
createNewModelMutation: UseMutationResult<
TModel,
Error,
TCreateModelArgs,
unknown
>;
}>({
formData: initialFormState,
setFormData: () => {},
Expand All @@ -117,6 +127,12 @@ const ModelCreationFormContext = createContext<{
TCreateTrainingDatasetArgs,
unknown
>,
createNewModelMutation: {} as UseMutationResult<
TModel,
Error,
TCreateModelArgs,
unknown
>,
});

export const ModelCreationFormProvider: React.FC<{
Expand All @@ -142,6 +158,15 @@ export const ModelCreationFormProvider: React.FC<{
) => {
setFormData((prev) => ({ ...prev, [field]: value }));
};
const trainingRequestMutation = useCreateModelTrainingRequest({mutationConfig:{
onSuccess:()=>{
notify("Training request submitted successfully", "success");
},
onError: (error) => {
const errorText = error?.response?.data[0] ?? "An error ocurred while submitting training request"
notify(errorText, "danger");
},
}});

const createNewTrainingDatasetMutation = useCreateTrainingDataset({
mutationConfig: {
Expand All @@ -157,7 +182,36 @@ export const ModelCreationFormProvider: React.FC<{
navigate(APPLICATION_ROUTES.CREATE_NEW_MODEL_TRAINING_AREA);
},
onError: () => {
notify("Error creating dataset", "danger");

notify("An error occurred while creating dataset", "danger");
},
},
});

const createNewModelMutation = useCreateModel({
mutationConfig: {
onSuccess: (data) => {
notify("Model created successfully", "success");
// Submit the model for training request
trainingRequestMutation.mutate({
model:data.id,
input_boundary_width:formData.boundaryWidth,
input_contact_spacing:formData.contactSpacing,
epochs:formData.epoch,
batch_size:formData.batchSize,
zoom_level:formData.zoomLevels

})

setFormData(initialFormState);

navigate(
`${APPLICATION_ROUTES.CREATE_NEW_MODEL_CONFIRMATION}?id=${data.id}`,

);
},
onError: () => {
notify("An error ocurred while creating model", "danger");
},
},
});
Expand All @@ -176,6 +230,7 @@ export const ModelCreationFormProvider: React.FC<{
setFormData,
handleChange,
createNewTrainingDatasetMutation,
createNewModelMutation,
}}
>
{children}
Expand Down
24 changes: 19 additions & 5 deletions frontend/src/app/routes/models/model-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import { useDialog } from "@/hooks/use-dialog";
import { APP_CONTENT, APPLICATION_ROUTES } from "@/utils";
import { useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";

import TrainingInProgressImage from "@/assets/images/training_in_prorgress.png";
import { Image } from "@/components/ui/image";
export const ModelDetailsPage = () => {
const { id } = useParams<{ id: string }>();
const { isOpened, closeDialog, openDialog } = useDialog();
Expand Down Expand Up @@ -64,10 +65,23 @@ export const ModelDetailsPage = () => {
<ModelDetailsSection
title={APP_CONTENT.models.modelsDetailsCard.propertiesSectionTitle}
>
<ModelDetailsProperties
trainingId={data?.published_training as number}
datasetId={data?.dataset}
/>
{!data?.published_training ? (
<div className="rounded-xl w-full h-80 border border-gray-border text-center flex flex-col gap-y-6 items-center justify-center text-gray">
<Image
src={TrainingInProgressImage}
alt="Model training in progress"
/>
<p className="max-w-lg">
Model training is not activated yet. Properties will be
available after a successful and activated training.
</p>
</div>
) : (
<ModelDetailsProperties
trainingId={data?.published_training as number}
datasetId={data?.dataset}
/>
)}
</ModelDetailsSection>
<div className="flex md:hidden">
<ButtonWithIcon
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions frontend/src/features/model-creation/api/create-models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { API_ENDPOINTS, apiClient } from "@/services";
import { TModel } from "@/types";

export type TCreateModelArgs = {
dataset: string;
base_model: string;
description: string;
name: string;
};

export const createModel = async ({
dataset,
name,
description,
base_model,
}: TCreateModelArgs): Promise<TModel> => {
return await (
await apiClient.post(`${API_ENDPOINTS.CREATE_MODELS}`, {
dataset,
name,
description,
base_model,
})
).data;
};
42 changes: 39 additions & 3 deletions frontend/src/features/model-creation/api/create-trainings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { API_ENDPOINTS, apiClient } from "@/services";
import { TTrainingAreaFeature, TTrainingDataset } from "@/types";
import {
TTrainingAreaFeature,
TTrainingDataset,
TTrainingDetails,
} from "@/types";

export type TCreateTrainingDatasetArgs = {
name: string;
Expand All @@ -13,7 +17,7 @@ export const createTrainingDataset = async ({
status = 0,
}: TCreateTrainingDatasetArgs): Promise<TTrainingDataset> => {
return await (
await apiClient.post(`${API_ENDPOINTS.CREATE_TRAINING_DATASETS}`, {
await apiClient.post(API_ENDPOINTS.CREATE_TRAINING_DATASETS, {
name,
source_imagery,
status,
Expand All @@ -31,9 +35,41 @@ export const createTrainingArea = async ({
geom,
}: TCreateTrainingAreaArgs): Promise<TTrainingAreaFeature> => {
return await (
await apiClient.post(`${API_ENDPOINTS.CREATE_TRAINING_AREA}`, {
await apiClient.post(API_ENDPOINTS.CREATE_TRAINING_AREA, {
dataset,
geom,
})
).data;
};

export type TCreateTrainingRequestArgs = {
batch_size: number;
epochs: number;
input_boundary_width: number;
input_contact_spacing: number;
model: string;
zoom_level: number[];
};

export const createTrainingRequest = async ({
batch_size,
epochs,
input_boundary_width,
input_contact_spacing,
model,
zoom_level,
}: TCreateTrainingRequestArgs): Promise<TTrainingDetails> => {
return await (
await apiClient.post(API_ENDPOINTS.CREATE_TRAINING_REQUEST, {
batch_size,
epochs,
description: "",
freeze_layer: false,
input_contact_spacing,
input_boundary_width,
model,
multimask: false,
zoom_level,
})
).data;
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@

import ModelCreationSuccess from "@/assets/images/model_creation_success.png";
import { Button } from "@/components/ui/button";
import { Image } from "@/components/ui/image";
import { Link } from "@/components/ui/link";
import { APPLICATION_ROUTES } from "@/utils";
import { useEffect } from "react";
import ConfettiExplosion from "react-confetti-explosion";
import { useNavigate, useSearchParams } from "react-router-dom";

const ModelCreationSuccessConfirmation = () => {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
// Model ID should be in the url params upon successful creation
const modelId = searchParams.get("id");

useEffect(() => {
if (!modelId) {
navigate(APPLICATION_ROUTES.MODELS);
}
}, [modelId]);

return (
<div className="flex items-center justify-center w-full h-full flex-col gap-y-10 text-center">
<ConfettiExplosion
Expand All @@ -13,14 +29,21 @@ const ModelCreationSuccessConfirmation = () => {
height={10000}
/>
<Image src={ModelCreationSuccess} alt="Model Creation Success Icon" />
<p className="text-title-2">Model 15 is Created!</p>
<p className="text-title-2">Model {modelId} is Created!</p>
<p className="text-gray">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore.
</p>
<div className="flex items-center justify-between gap-x-4">
<Button>go to model</Button>
<Button variant="dark">Explore My models</Button>
<Link
href={`${APPLICATION_ROUTES.MODELS}/${modelId}`}
title="go to model"
>
<Button>go to model</Button>
</Link>
<Link href={`${APPLICATION_ROUTES.MODELS}`} title="go to model">
<Button variant="dark">Explore models</Button>
</Link>
</div>
</div>
);
Expand Down
22 changes: 16 additions & 6 deletions frontend/src/features/model-creation/components/model-summary.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useModelFormContext } from "@/app/providers/model-creation-provider";
import {
DatabaseIcon,
MapIcon,
// MapIcon,
// RAMIcon,
SaveIcon,
Expand All @@ -11,6 +12,9 @@ import {
} from "@/components/ui/icons";
import { StepHeading } from "@/features/model-creation/components/";
import { IconProps } from "@/types";
import { APPLICATION_ROUTES } from "@/utils";
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";

const SummaryItem = ({
icon: Icon,
Expand Down Expand Up @@ -60,13 +64,13 @@ const ModelSummaryStep = () => {
label: "Dataset ID",
content: formData.selectedTrainingDatasetId,
},
// These will be retrieved from API.

// { icon: RAMIcon, label: "Dataset Size", content: "250 Images" },
// {
// icon: MapIcon,
// label: "Open Aerial Imagery",
// content: "San Jose Mission 10C Flight 1",
// },
{
icon: MapIcon,
label: "Open Aerial Imagery",
content: "",
},
{
icon: ZoomInIcon,
label: "Zoom Levels",
Expand All @@ -83,6 +87,12 @@ const ModelSummaryStep = () => {
],
},
];
const navigate = useNavigate()
useEffect(() => {
if (!formData.modelName && !formData.modelDescription) {
navigate(APPLICATION_ROUTES.MODELS);
}
}, [formData]);

return (
<div className="flex flex-col gap-y-6">
Expand Down
Loading

0 comments on commit 99f6220

Please sign in to comment.