alexander add env

This commit is contained in:
IDONTSUDO 2024-06-26 18:19:06 +03:00
parent 50d0c4c12b
commit b5750b12ef
12 changed files with 301 additions and 40 deletions

View file

@ -7,7 +7,7 @@ export enum HttpMethod {
GET = "GET",
POST = "POST",
DELETE = "DELETE",
PUT = "PUT"
PUT = "PUT",
}
export class HttpError extends Error {
status: number;
@ -20,10 +20,7 @@ export class HttpError extends Error {
}
export class HttpRepository {
private server = "http://localhost:4001";
public async _formDataRequest<T>(method: HttpMethod, url: string, data?: any): Promise<Result<HttpError, T>> {
let formData = new FormData();
formData.append("file", data);
public async _formDataRequest<T>(method: HttpMethod, url: string, formData: FormData): Promise<Result<HttpError, T>> {
const reqInit = {
body: formData,
method: method,

View file

@ -56,6 +56,8 @@ export interface IMainPageProps {
maskLoader?: boolean;
error?: UiBaseError[];
}
export const MainPage = (props: IMainPageProps) => {
const blocksNames = [
{ name: "Детали", path: DetailsScreenPath, icon: "Setting" },

View file

@ -83,7 +83,5 @@ export function CoreText(props: ITextProps) {
{props.text}
</div>
);
}
// CREATE COMPONENT , HTML WRITE , JSX->JS TSX -> TS, PROPS , LIFE CYCLE , REACT HOOK, STATE MANAGMENT -> PUBSUB -> Конечный автомат -> ROUTER

View file

@ -15,7 +15,9 @@ export class ProjectHttpRepository extends CoreHttpRepository {
return await this._jsonRequest<UUID>(HttpMethod.POST, "/projects", model);
}
async setProjectRootFile(file: File, projectId: string) {
return await this._formDataRequest(HttpMethod.POST, `/projects/upload?id=${projectId}`, file);
const formData = new FormData();
formData.append("file", file);
return await this._formDataRequest(HttpMethod.POST, `/projects/upload?id=${projectId}`, formData);
}
async setActivePipeline(id: string) {

View file

@ -1,12 +1,19 @@
import { HttpMethod, CoreHttpRepository } from "../../core/repository/http_repository";
import { EnvelopmentViewModel } from "./envelopment_view_model";
export interface Parts {
name: string;
part_path: string;
material_path: string;
stlUrl: string;
image: string;
name: string;
part_path: string;
material_path: string;
stlUrl: string;
image: string;
}
export class DetailsHttpRepository extends CoreHttpRepository {
}
uploadNewEnv = (model: EnvelopmentViewModel) => {
const formData = new FormData();
Object.entries(model).forEach(([k, v]) => {
formData.append(k, v);
});
this._formDataRequest(HttpMethod.POST, "/projects/upload/env", formData);
};
}

View file

@ -1,8 +1,11 @@
import { observer } from "mobx-react-lite";
import { DetailsStore } from "./details_store";
import { DetailsStore, DrawersDetailsStore } from "./details_store";
import { MainPage } from "../../core/ui/pages/main_page";
import React, { useEffect } from "react";
import React from "react";
import { CoreText, CoreTextType } from "../../core/ui/text/text";
import { CoreButton } from "../../core/ui/button/button";
import { Drawer, Upload } from "antd";
import { CoreInput } from "../../core/ui/input/input";
export const DetailsScreenPath = "/details";
@ -20,6 +23,12 @@ export const DetailsScreen = observer(() => {
bodyChildren={<canvas ref={canvasRef} style={{ overflow: "hidden", width: "100%" }} />}
panelChildren={
<>
<CoreButton
filled={true}
onClick={() => store.editDrawer(DrawersDetailsStore.NewEnvelopment, true)}
text="Добавить окружение"
style={{ margin: 10 }}
/>
{store.detailsViewModel.map((el, i) => (
<div key={i} onClick={() => store.selectedDetail(el.label)} style={{ margin: 5, cursor: "pointer" }}>
<div style={el.selected ? { width: "100%", background: "#E8DEF8", borderRadius: 100 } : {}}>
@ -31,6 +40,37 @@ export const DetailsScreen = observer(() => {
</div>
</div>
))}
<Drawer
title={store.titleDrawer}
destroyOnClose={true}
onClose={() => store.editDrawer(DrawersDetailsStore.NewEnvelopment, false)}
open={store.drawers.find((el) => el.name === DrawersDetailsStore.NewEnvelopment)?.status}
>
<CoreInput label="имя" onChange={(text) => store.updateForm({ name: text })} />
<Upload onChange={(file) => store.updateForm({ blend: file.file.originFileObj })}>
<CoreButton filled={true} text="blend" />
</Upload>
<Upload onChange={(file) => store.updateForm({ ply: file.file.originFileObj })}>
<CoreButton filled={true} text="ply" />
</Upload>
<Upload onChange={(file) => store.updateForm({ stl: file.file.originFileObj })}>
<CoreButton filled={true} text="stl" />
</Upload>
<Upload onChange={(file) => store.updateForm({ glb: file.file.originFileObj })}>
<CoreButton filled={true} text="glb" />
</Upload>
<Upload onChange={(file) => store.updateForm({ dae: file.file.originFileObj })}>
<CoreButton filled={true} text="dae" />
</Upload>
<Upload onChange={(file) => store.updateForm({ fbx: file.file.originFileObj })}>
<CoreButton filled={true} text="fbx" />
</Upload>
<Upload onChange={(file) => store.updateForm({ png: file.file.originFileObj })}>
<CoreButton filled={true} text="png" />
</Upload>
<div style={{ height: 10 }} />
<CoreButton text="Сохранить" onClick={() => store.uploadEnv()} />
</Drawer>
</>
}
/>

View file

@ -1,27 +1,32 @@
import makeAutoObservable from "mobx-store-inheritance";
import { CoreError, UiErrorState } from "../../core/store/base_store";
import { CoreError, UiDrawerFormState } from "../../core/store/base_store";
import { NavigateFunction } from "react-router-dom";
import { DetailsHttpRepository, Parts } from "./details_http_repository";
import { DetailsThreeRepository } from "./details_three_repository";
import { EnvelopmentViewModel } from "./envelopment_view_model";
import { message } from "antd";
interface IDetailViewModel {
label: string;
selected: boolean;
httpUrl: string;
}
export enum DrawersDetailsStore {
NewEnvelopment = "Новое окружение",
}
export class DetailsStore extends UiErrorState<CoreError> {
export class DetailsStore extends UiDrawerFormState<EnvelopmentViewModel, CoreError> {
viewModel: EnvelopmentViewModel = EnvelopmentViewModel.empty();
detailsViewModel: IDetailViewModel[] = [];
parts: Parts[] = [];
detailsHttpRepository: DetailsHttpRepository = new DetailsHttpRepository();
detailsThreeRepository?: DetailsThreeRepository;
constructor() {
super();
super(DrawersDetailsStore);
makeAutoObservable(this);
this.init();
}
errorHandingStrategy = (error: CoreError) => { };
errorHandingStrategy = (error: CoreError) => {};
init = async (navigate?: NavigateFunction | undefined): Promise<void> => {
await this.mapOk("parts", this.detailsHttpRepository.getAssetsActiveProject());
this.detailsViewModel = this.parts.map((el) => {
@ -41,16 +46,24 @@ export class DetailsStore extends UiErrorState<CoreError> {
this.detailsViewModel.map((el) => {
if (el.label.match(label)) {
el.selected = true;
this.detailsThreeRepository?.deleteAllObjectsScene()
this.detailsThreeRepository?.loadHttpAndPreview(el.httpUrl, el.label, () => { })
this.detailsThreeRepository?.deleteAllObjectsScene();
this.detailsThreeRepository?.loadHttpAndPreview(el.httpUrl, el.label, () => {});
return el;
}
return el
return el;
});
};
loadScene = async (ref: HTMLCanvasElement) => {
this.detailsThreeRepository = new DetailsThreeRepository(ref, () => { });
this.detailsThreeRepository = new DetailsThreeRepository(ref, () => {});
this.detailsThreeRepository.render();
};
uploadEnv = () =>
this.viewModel.isValid().fold(
async (model) => {
await this.detailsHttpRepository.uploadNewEnv(model);
await this.init();
this.editDrawer(DrawersDetailsStore.NewEnvelopment, false);
},
async (e) => message.error(e)
);
}

View file

@ -0,0 +1,32 @@
import { Result } from "../../core/helper/result";
export class EnvelopmentViewModel {
public name: string;
public blend?: File;
public ply?: File;
public glb?: File;
public dae?: File;
public stl?: File;
public fbx?: File;
public png?: File;
public mass: number = 0;
public inertia = {
ixx: 0.1,
ixy: 0,
ixz: 0,
iyy: 0.1,
iyz: 0,
izz: 0.1,
};
constructor(name: string) {
this.name = name;
}
static empty = () => new EnvelopmentViewModel("");
isValid = (): Result<string, EnvelopmentViewModel> => {
if (this.name.isEmpty()) {
return Result.error("name is empty");
}
return Result.ok(this);
};
}