webstudio/ui/src/features/skills/skills_screen.tsx
2025-01-18 15:29:07 +03:00

290 lines
No EOL
11 KiB
TypeScript

import { observer } from "mobx-react-lite";
import { DrawersSkills, SkillsStore } from "./skills_store";
import { Drawer, Modal, message } from "antd";
import { CoreInput } from "../../core/ui/input/input";
import { CoreText, CoreTextType } from "../../core/ui/text/text";
import { TopicViewModel } from "../topics/topic_view_model";
import { BtAction, BtActionViewModel, ISkill, SkillModel } from "../../core/model/skill_model";
import { btDependencyFormBuilder } from "../behavior_tree_builder/presentation/ui/forms/forms";
import { CoreButton } from "../../core/ui/button/button";
import { CoreSelect } from "../../core/ui/select/select";
import { useStore } from "../../core/helper/use_store";
import { FormBuilder } from "../../core/ui/form_builder/form_builder";
import { ButtonV2 } from "../../core/ui/button/button_v2";
import { Result } from "../../core/helper/result";
export const isValidJson = <T,>(json: any): Result<string, T> => {
try {
return Result.ok(JSON.parse(json));
} catch {
return Result.error(`is not json type: ${json}`);
}
};
export const SkillsScreenPath = "/skills";
export const SkillsScreen = observer(() => {
const store = useStore(SkillsStore);
return (
<>
<div>
<CoreButton
style={{ width: 100 }}
text="new skill"
onClick={() => store.editDrawer(DrawersSkills.newSkill, true)}
/>
<CoreButton
style={{ width: "max-content" }}
text="import skill"
onClick={() => store.editDrawer(DrawersSkills.importSkill, true)}
/>
{store.skills?.map((el) => (
<div
style={{
backgroundColor: "coral",
width: "max-content",
margin: 10,
padding: 10,
borderRadius: 20,
}}
>
<CoreText text="Delete" type={CoreTextType.header} onClick={() => store.deleteSkill(el._id as string)} />
<CoreText text="Copy" type={CoreTextType.header} onClick={() => store.copySkill(el)} />
<CoreText text={`skill server name:${el.Module.name}`} type={CoreTextType.header} />
<div>
<CoreText text={"Topics"} type={CoreTextType.header} />
{el.topicsOut.map((el) => (
<div>
<div>{el.name}</div>
<div>{el.type}</div>
</div>
))}
<CoreText text={"actions"} type={CoreTextType.header} />
{el.BTAction.map((el) => (
<div>
<CoreText text={el.name} type={CoreTextType.medium} />
{el.param.map((element) => (
<div>
<div>{element.type}</div>
<div>{JSON.stringify(element.dependency)}</div>
</div>
))}
</div>
))}
</div>
</div>
))}
</div>
<Drawer
width={(window.innerWidth / 100) * 50}
title={store.titleDrawer}
destroyOnClose={true}
onClose={() => store.editDrawer(DrawersSkills.importSkill, false)}
open={store.drawers.find((el) => el.name === DrawersSkills.importSkill)?.status}
>
<div style={{ display: "flex", flexDirection: "column", justifyContent: "space-between", height: "100%" }}>
<CoreInput
style={{ height: "max-content" }}
styleContentEditable={{ height: "max-content" }}
label="JSON навыка"
onChange={(text) => store.importSkill(text)}
/>
</div>
</Drawer>
<Drawer
width={(window.innerWidth / 100) * 50}
title={store.titleDrawer}
destroyOnClose={true}
onClose={() => store.editDrawer(DrawersSkills.newSkill, false)}
open={store.drawers.find((el) => el.name === DrawersSkills.newSkill)?.status}
>
<div style={{ display: "flex", flexDirection: "column", justifyContent: "space-between", height: "100%" }}>
<div>
<CoreInput
trim={true}
label={"name"}
onChange={(text) =>
store.updateForm({ SkillPackage: Object.assign(store.viewModel.SkillPackage, { name: text }) })
}
/>
<CoreInput
trim={true}
label={"format"}
onChange={(text) =>
store.updateForm({ SkillPackage: Object.assign(store.viewModel.SkillPackage, { format: text }) })
}
/>
<CoreInput
trim={true}
label="version"
onChange={(text) =>
store.updateForm({ SkillPackage: Object.assign(store.viewModel.SkillPackage, { version: text }) })
}
/>
<CoreInput
trim={true}
label={"Module description"}
onChange={(text) =>
store.updateForm({ Module: Object.assign(store.viewModel.Module, { description: text }) })
}
/>
<CoreInput
trim={true}
label={"Module name"}
onChange={(text) => store.updateForm({ Module: Object.assign(store.viewModel.Module, { name: text }) })}
/>
<CoreInput
trim={true}
label={"Module node name"}
onChange={(text) =>
store.updateForm({ Module: Object.assign(store.viewModel.Module, { node_name: text }) })
}
/>
<CoreInput
trim={true}
label="Launch package"
onChange={(text) =>
store.updateForm({ Launch: Object.assign(store.viewModel.Launch, { package: text }) })
}
/>
<CoreInput
trim={true}
label="Launch executable"
onChange={(text) =>
store.updateForm({ Launch: Object.assign(store.viewModel.Launch, { executable: text }) })
}
/>
<CoreInput
label="Settings form builder result"
style={{ height: "min-content" }}
styleContentEditable={{ height: "min-content" }}
onChange={(text) =>
store.updateForm({ Settings: Object.assign(store.viewModel.Settings, { result: text }) })
}
/>
<CoreInput
label="Settings form builder context"
style={{ height: "min-content" }}
styleContentEditable={{ height: "min-content" }}
onChange={(text) =>
store.updateForm({ Settings: Object.assign(store.viewModel.Settings, { context: text }) })
}
/>
<ButtonV2 text="form builder modal" onClick={() => (store.formBuilderModal = true)} />
<Modal
destroyOnClose={true}
open={store.formBuilderModal}
footer={null}
closable={false}
closeIcon={null}
onCancel={store.handleFormBuilderModalCancel}
>
<FormBuilder
formBuilder={store.viewModel.Settings}
onChange={(form) => store.updateForm({ Settings: form })}
/>
<ButtonV2 text="save" onClick={() => store.handleFormBuilderModalCancel()} />
</Modal>
<CoreText
text={`Topics ${store.viewModel.topicsOut.length}`}
type={CoreTextType.large}
onClick={() => store.updateForm({ topicsOut: store.viewModel.topicsOut.add(TopicViewModel.empty()) })}
/>
<div>
{store.viewModel.topicsOut.map((el, index) => (
<div key={index} style={{ marginTop: 10 }}>
<CoreInput
trim={true}
value={el.name}
label={"name"}
onChange={(text) =>
store.updateForm({ topicsOut: store.viewModel.topicsOut.replacePropIndex({ name: text }, index) })
}
/>
<CoreInput
trim={true}
value={el.type}
label={"type"}
onChange={(text) =>
store.updateForm({ topicsOut: store.viewModel.topicsOut.replacePropIndex({ type: text }, index) })
}
/>
</div>
))}
</div>
<CoreText
text={`BTAction ${store.viewModel.BTAction.length}`}
type={CoreTextType.large}
onClick={() => store.updateForm({ BTAction: store.viewModel.BTAction.add(BtActionViewModel.empty()) })}
/>
{store.viewModel.BTAction.map((el, index) => (
<div key={index} style={{ marginTop: 10 }}>
<CoreInput
trim={true}
value={el.name}
label={"name"}
onChange={(text) =>
store.updateForm({ BTAction: store.viewModel.BTAction.replacePropIndex({ name: text }, index) })
}
/>
<CoreInput
trim={true}
value={el.type}
label={"type"}
onChange={(text) =>
store.updateForm({ BTAction: store.viewModel.BTAction.replacePropIndex({ type: text }, index) })
}
/>
<CoreSelect
items={Object.keys(BtAction)}
value={el.typeAction}
label={"type action"}
onChange={(value: string) =>
store.updateForm({
BTAction: store.viewModel.BTAction.replacePropIndex({ typeAction: value as BtAction }, index),
})
}
/>
<CoreText
text={`Param ${el.param.length}`}
type={CoreTextType.large}
onClick={() => store.addNewParam(index)}
/>
{el.param.map((param) => (
<div style={{ border: "1px solid", padding: 10, margin: 1 }} onClick={() => store.modalShow()}>
<div>{param.type}</div>
<div> {JSON.stringify(param.dependency)}</div>
</div>
))}
</div>
))}
</div>
<CoreButton text="Save" style={{ width: 100 }} onClick={() => store.saveNewSkill()} />
</div>
</Drawer>
<Modal
destroyOnClose={true}
afterClose={() => (store.selectParam = undefined)}
open={store.isModalOpen}
footer={null}
closable={false}
closeIcon={null}
onCancel={store.handleCancel}
>
<CoreText text={"Выберите параметр"} type={CoreTextType.large} />
{store.selectParam !== undefined
? store.selectParam.component
: btDependencyFormBuilder((dependency) => store.onChangeBtDependency(dependency)).map((el) => (
<div onClick={() => store.clickParam(el)}>{el.form}</div>
))}
</Modal>
</>
);
});