Skip to content

Commit

Permalink
Added "Add Instance from Profile" feature
Browse files Browse the repository at this point in the history
  • Loading branch information
RicYaben committed Sep 6, 2022
1 parent 30b4722 commit 346b365
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 30 deletions.
13 changes: 11 additions & 2 deletions ui/src/components/modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ type ModalProps = {
* This component is used for regular modals
* {title, icon, content} : {title: string, icon: any, content: any}
*/
const CenteredModal = ({ props }: { props: ModalProps }) => {
const CenteredModal = ({
props,
children,
}: {
props: ModalProps;
children?: any;
}) => {
return (
<Modal
{...props}
Expand All @@ -30,7 +36,10 @@ const CenteredModal = ({ props }: { props: ModalProps }) => {
{props.title}
</Modal.Title>
</Modal.Header>
<Modal.Body>{props.content}</Modal.Body>
<Modal.Body>
{children}
{props.content}
</Modal.Body>
<Modal.Footer></Modal.Footer>
</Modal>
);
Expand Down
27 changes: 27 additions & 0 deletions ui/src/routes/instances/InstanceAPI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,30 @@ export const changeProxyStatus = async (
console.log(err);
}
};

// Iterate trhough the services and add them to the host
export const addFromProfile = async (host: string, services: Service[]) => {
for (const service of services) {
try {
await fetch("http://" + host + "/api/services/new/", {
method: "POST",
body: JSON.stringify({
name: service.name,
host: service.host,
port: Number(service.port),
network: service.network.value,
interaction: service.interaction.value,
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
},
})
.then((response) => response.json())
.catch((err) => {
console.log(err.message);
});
} catch (err) {
console.log(err);
}
}
};
89 changes: 61 additions & 28 deletions ui/src/routes/instances/InstancesUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { getPage } from "../../constants/globals";

import { Service } from "../../recoil/atoms/services";
import { Profile, profiles } from "../../recoil/atoms/profiles";
import { useRecoilCallback, useRecoilValue } from "recoil";
import { useRecoilCallback, useRecoilValue, useResetRecoilState } from "recoil";
import {
instances,
instanceIds,
Expand All @@ -20,14 +20,22 @@ import {
} from "../../recoil/atoms/instances";
import { SimpleForm } from "../../components/forms/Form";
import { InstanceFormFields } from "./InstanceForm";

const CustomInstanceDropdownItem = () => {
import { addFromProfile } from "./InstanceAPI";

const CustomInstanceDropdownItem = ({
show = false,
setShow,
}: {
show?: boolean;
setShow: any;
}) => {
const pageName = "Instances";
const page = getPage(pageName);

const [modalShow, setModalShow] = React.useState(false);

const ids = useRecoilValue(instanceIds);
const defaultValues = useRecoilValue(instanceFormFields);
const resetFormFields = useResetRecoilState(instanceFormFields);

const onSubmit = useRecoilCallback(({ set }) => (instance: Instance) => {
const id = ids.length;
// Set the new id in the list
Expand All @@ -36,12 +44,20 @@ const CustomInstanceDropdownItem = () => {
const newInstnace = {
...instance,
id: id,
profile: defaultValues.profile,
};

// Set the new instance
set(instances(id), (prev) => ({ ...prev, ...newInstnace }));
});

const defaultValues = useRecoilValue(instanceFormFields);
// Contact the API to create all the services
if (newInstnace.profile?.services) {
addFromProfile(newInstnace.host, newInstnace.profile.services);
}

// Reset the form fields
resetFormFields();
});

const content = (
<SimpleForm
Expand All @@ -56,19 +72,31 @@ const CustomInstanceDropdownItem = () => {

const props = {
title: "New Custom Instance",
onHide: () => setModalShow(false),
show: modalShow,
onHide: () => {
setShow(false);
resetFormFields();
},
show: show,
content: content,
icon: page?.icon,
};

const profileIcon = getPage("Profiles");

return (
<>
<Dropdown.Item onClick={() => setModalShow(true)} id="custom add">
<Dropdown.Item onClick={() => setShow(true)} id="custom add">
<AiOutlinePlus />
Custom Instance
</Dropdown.Item>
<CenteredModal props={props} />
<CenteredModal props={props}>
{defaultValues.profile && (
<span>
{profileIcon && <profileIcon.icon />}
{defaultValues.profile.name}
</span>
)}
</CenteredModal>
</>
);
};
Expand Down Expand Up @@ -104,7 +132,6 @@ const InstancesAddProfileDropdownMenu = React.forwardRef(
!value || child.props.profile.name.toLowerCase().startsWith(value)
)}
</ul>
<CustomInstanceDropdownItem />
</div>
);
}
Expand Down Expand Up @@ -146,25 +173,23 @@ export const ProfileRowInfoPop = ({ services }: { services: Service[] }) => {
);
};

const ProfileDropdownRow = ({ profile }: { profile: Profile }) => {
const ids = useRecoilValue(instanceIds);

const insertInstance = useRecoilCallback(
({ set }) =>
(id: number, prof: Profile) => {
// Set the new id in the list
set(instanceIds, [...ids, id]);

// Set the instance in teh family
const newInstance = { name: prof.name, id: id, profile: prof };
set(instances(id), (prev) => ({ ...prev, ...newInstance }));
}
);
const ProfileDropdownRow = ({
profile,
setShow,
}: {
profile: Profile;
setShow: any;
}) => {
const insertInstance = useRecoilCallback(({ set }) => (prof: Profile) => {
// Set the new id in the list
set(instanceFormFields, (prev) => ({ ...prev, profile: prof }));
setShow(true);
});

return (
<Dropdown.Item
onClick={() => {
insertInstance(ids.length, profile);
insertInstance(profile);
}}
>
{profile.name}
Expand All @@ -176,6 +201,7 @@ const ProfileDropdownRow = ({ profile }: { profile: Profile }) => {
const AddButton = () => {
// Get all the profiles
const profs = useRecoilValue(profiles);
const [modalShow, setModalShow] = React.useState(false);

return (
<Dropdown drop="start">
Expand All @@ -184,8 +210,15 @@ const AddButton = () => {
</Dropdown.Toggle>
<Dropdown.Menu as={InstancesAddProfileDropdownMenu}>
{profs.map((profile: Profile) => {
return <ProfileDropdownRow profile={profile} key={profile.id} />;
return (
<ProfileDropdownRow
profile={profile}
key={profile.id}
setShow={setModalShow}
/>
);
})}
<CustomInstanceDropdownItem show={modalShow} setShow={setModalShow} />
</Dropdown.Menu>
</Dropdown>
);
Expand Down

0 comments on commit 346b365

Please sign in to comment.